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
andbar1
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
.