简体   繁体   中英

understanding how to dynamically create an array of structure and access its elements

I need to pass the address of a pointer to a structure to a function, which inturn will dynamically allocate the memory for an array of structures and fill in the values.

Now from my calling method, once i return from the func1, i should be able to iterate through the array of structure and display the value of the structure variables.

Can someone explain how to pass the address of the pointer to the structure, also iterating through the array of structures created dynamically ?

my sample code looks like this:

struct test {
    int a;
    int b;
};

void func1(int *n,struct test **testobj)

{
    n=5;
    *testobj = (struct test*) malloc(n*sizeof(struct test));
    for(i=0;i<n;i++)
    {
        (*testobj)[i].a=1;
        (*testobj)[i].b=2;
    }
}

int main()
{
    struct test testobj;int n;
    func1(&n,&testobj);
    for(i=0;i<n;i++)
    {
        printf("%d %d",(*testobj)[i].a,*testobj)[i].b);
    }
    free(testobj);
}

In main() define a pointer to a test structure:

struct test *testPtr;

To take the address of that pointer use the & address-of operator:

&testPtr;

This returns the address of the pointer and has type struct test **

You can then pass this into your function func1 , which does the correct allocation (although casting malloc() is generally considered bad practice - Do I cast the result of malloc? ). Other than that func1() looks good... the line...

*testobj = malloc(n*sizeof(struct test));

... is correct. *testobj dereferences your double pointer that you got by doing &testPtr , and stores the address of the new memory in your pointer. You are also correct when you dereference your double-pointer using (*testobj)[i] because [] has higher precedence than * you needed to (as you've correctly done) surround the dereference with brackets to make sure that happens before you take the index.

Thus, when func1() returns the pointer testPtr should now point to the array of n test structures you allocated and can be accessed using testPtr[i].a etc.

EDIT: Your for loop should become

for(i=0;i<n;i++)
    printf("%d %d", testobj[i].a, testobj[i].b);

Your original for loop should have given you compilation errors? In the original code testobj is not a pointer, therefore dereferencing it should not be possible.

So the summary answer is in main() declare testobj as a pointer and then access the array elements as testobj[n] :)

EDIT: As eric has pointed out, remove n=5; from func1() . I think you meant *n=5 perhaps as some kind of debugging step... You probably mean to use n as the input to the function to say how many objects you want in your structure array. Either initialise n or perhaps re-define func1() to be

void func1(int n,struct test **testobj) // n is no longer a poitner, just a number

create your array of pointers to structures in declaration step itself and simply pass it to the function

struct test *testobj[10];
func1(&n,testobj);

This passes the whole array of pointers to the function

Your code appears pretty much ok to me. only edit that should make it fine is--

in place of

struct test testobj;

put the following code

struct test  *testobj;

and keep the remaining as it is..!

here's the working version of what's required, here the memory is allocated in the called function just as required

#include <stdlib.h>
#include <stdio.h>
struct tests {
    int a;
    int b;
};

void func1(int *n,struct tests **testobj)

{
    int i;
    *n=5;
    *testobj = (struct tests*) malloc((*n)*sizeof(struct tests));
    for(i=0;i<(*n);i++)
    {
        (*testobj)[i].a=1;
        (*testobj)[i].b=2;
    }
}

int main()
{
    int i;
    struct tests *testobj;int n;
    func1(&n,&testobj);
    for(i=0;i<(n);i++)
    {
        printf("%d %d",(testobj)[i].a,testobj[i].b);
    }
    free(testobj);
}

It isn't entirely clear which version you're asking for, but one of these should cover it:

/* allocate some number of tests.
 *
 * out_n: out parameter with array count
 * returns: an array of tests
 */
struct test* allocate_some_tests(int *out_n) {
    int n = 5; /* hardcoded, random or otherwise unknown to caller */
    *out_n = n
    struct test *t = malloc(n * sizeof(*t));
    while (n--) {
        t[n].a = 1;
        t[n].b = 2;
    }
    return t;
}

/* allocate a specific number of tests.
 *
 * n: in parameter with desired array count
 * returns: an array of tests
 */
struct test* allocate_n_tests(int n) {
    struct test *t = malloc(n * sizeof(*t));
    while (n--) {
        t[n].a = 1;
        t[n].b = 2;
    }
    return t;
}

Note that you can just return the allocated array, you don't need a pointer-to-pointer here.

As for calling them, and iterating over the result:

void print_tests(struct test *t, int n) {
    for (; n--; t++)
        printf("{%d, %d}\n", t->a, t->b);
}

int main()
{
    int count1; /* I don't know how many yet */
    struct test *array1 = allocate_some_tests(&count1);
    print_tests(array1, count1);

    int count2 = 3; /* I choose the number */
    struct test *array2 = allocate_n_tests(count2);
    print_tests(array2, count2);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM