I have the following struct with a flexible array member:
struct test {
size_t sz;
const char str[];
};
Now I want to allocate some memory to put this struct continuously (like in array). The problem is a declaration like struct test test_arr[]
is undefined behavior. 6.7.2.1(p3)
:
the last member of a structure with more than one named member may have incomplete array type; such a structure (and any union containing, possibly recursively, a member that is such a structure) shall not be a member of a structure or an element of an array.
We know that pointer returned by malloc
can be converted to a pointer to any objecut type with fundamental alignment. Consider the following code:
void *obj= malloc(100 * sizeof(struct test)); //enough memory
struct test *t1 = obj;
t1 -> sz = 2;
t1 -> str = {'a', 'b'};
struct test *t2 = (void *) (((char *) obj) + sizeof(struct test) + sizeof(char[2])); // non conforming
What is the conforming way of doing so?
A struct
with a flexible array member can't be a member of an array, as dictated by the quote you gave.
The best way to handle this is to change the flexible array member to a pointer and allocate space for it separately.
struct test {
size_t sz;
char *str;
};
...
struct test *arr = malloc(100 * sizeof(struct test));
arr[0].sz = 2;
arr[0].str = malloc(2);
arr[0].str[0] = 'a';
arr[0].str[1] = 'b';
arr[1].sz = 3;
arr[1].str = malloc(3);
arr[1].str[0] = 'c';
arr[1].str[1] = 'd';
arr[1].str[2] = 'e';
Also, it's generally not a good idea to have const
members of a struct.