Home > Mobile >  Dereferencing a pointer inside a designated struct initializer in C
Dereferencing a pointer inside a designated struct initializer in C

Time:03-29

Let's say I have the following struct

typedef struct foo {
    int    a;
    char **b;
} foo;

And this is what I am trying to do

char *bar0 = malloc(sizeof *bar0);
char *bar1 = malloc(sizeof *bar1);

foo f = {
    .a    = 4,
    .b    = malloc(2 * sizeof(char *)),
    .b[0] = bar0, // not allowed!
    .b[1] = bar1, // not allowed!
}

GCC errors out as array index in non-array initializer. I have also tried .(*b) = bar0 and .(*(b 1)) = bar1, but they aren't syntactically valid too.

EDIT: Is there any way to assign bar0 and bar1 within the initializer , and not use separate assignment expressions?

CodePudding user response:

Is there any way to assign bar0 and bar1 within the initializer , and not use separate assignment expressions?

No, f.b is a pointer to an allocated object (returned by a call to malloc in this case) and an allocated object cannot be initialized using an initializer. Just remove the problematic designated initializers and use assignment expressions instead:

char *bar0 = malloc(sizeof *bar0);
char *bar1 = malloc(sizeof *bar1);

foo f = {
    .a    = 4,
    .b    = malloc(2 * sizeof(char *)),
};
f.b[0] = bar0;
f.b[1] = bar1;

CodePudding user response:

b is a pointer (to a pointer) not an array, so you cannot use array designated initializer syntax. Furthermore, you cannot have run-time allocation with malloc an initialization at the same time.

You'll have to do something like:

char *bar0 = malloc(something_meaningful);
char *bar1 = malloc(something_meaningful);
foo f = {
    .a    = 4,
    .b    = (char*[]){ bar0, bar1 }
};

This assigns b to a compound literal with the same scope as f. However, you won't be able to re-size b itself now. If that's a requirement, then you have to do malloc run-time assignement in two separate steps.


Please note that char *bar0 = malloc(sizeof *bar0); is quite senseless if you have to realloc this 1 byte the first thing you do anyway. I'd recommend to either allocate a "reasonably large chunk" or set it to NULL.

  • Related