As the title states I was wondering how arrays of C-structs with a flexible array member behaves. Here is an example:
struct vector {
size_t length;
double array[];
};
The Wikipedia article says:
The
sizeof
operator on such a struct is required to give the offset of the flexible array member.
On my machine this corresponds to 8 bytes (sizeof(size_t)
). But what happens, when I do the following:
Obviously the array cannot hold the data of vector v0
, since it's only 3*8 bytes = 24 bytes wide. How can I deal with situations like this?
#define LENGTH 10
int main() {
struct vector arr[3];
struct vector *v0 = calloc(1, sizeof(*v0) + LENGTH * sizeof(v0->array[0]));
v0->length = LENGTH;
size_t i;
for (i = 0; i < v0->length; i++) {
v0->array[i] = (double) i;
}
struct vector v1;
struct vector v2;
arr[0] = *v0;
arr[1] = v1;
arr[2] = v2;
for (i = 0; i < arr[0].length; i++) {
printf("arr[0].array[%2zu] equals %2.0lf.\n", i, arr[0].array[i]);
printf(" v0->data[%2zu] equals %2.0lf.\n", i, v0->array[i]);
}
return 0;
}
For example, when I'm writing a library (header: mylib.h
, source: my lib.c
) and want to hide the implementation of one specific struct from the user (struct declared in header, defined in source - hidden). Sadly exactly this struct contains a flexible array member. Won't this lead to unexpected behavior, when the user tries to create an array of named structures?
Extra: Read more about the flexible array in the OpenSTD C Spec.
Just search for 'flexible array member'.
EDIT: The latest draft of the C11 Standard, the most up to date freely available reference for the C language is available here: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
sizeof (struct mystruct) + array[0].length* sizeof (array[0].data[0]) + sizeof (struct mystruct) + array[1].length* sizeof (array[1].data[1]) + sizeof (struct mystruct) + array[2].length* sizeof (array[2].data[2]) + ...
? That's kind of nice I guess.. I'm pretty sure that's not the way to handle structures like this properly. It would be way more efficient to avoid the flexible array member, do an extra malloc and use the good old style data pointer-member. – Pulverizearr[i] = ...
you are copying only the firstsizeof(size_t)
bytes intoarr[i]
. – Equip