I need to return a structure with a flexible array member from a C function but can't figure out why it doesn't compile. I know that returning arrays can be achieved by encapsulating them in a struct as follows:
struct data_array {
long length;
double data[];
};
My function looks like this:
struct data_array test (int length) {
struct data_array a;
double* b = malloc (1000);
a.length = 1000;
a.data = b;
return a;
}
However, the compiler returns: "invalid use of flexible array member".
According to the book "21st Century C", the data array in the struct is handled as a pointer (which makes perfectly sense to me). It has not been initialized and therefore there should be no memory been allocated for it to hold its data. (even the compiler doesn't know how much memory is needed for it). So I have to allocate the memory and assign it to my return variable.
So, why does the compiler returns an error? And how can I solve this problem?
you are trying to change base address of the array at line
It is not possible to modify the array base address, array base address is a constant pointer.
Few things:
1) change the struct defenation to:
2) This is how you should use malloc to allocate memory for your array:
EDIT
There are too many mistakes, just follow this code:
NOTE that you might need to add casting to the types when useing maloc (my visual force me to do so, otherwise it's compile error. But it simply worng).
Structs with flexible array members like yours (where the size of
data
is not given in the struct definition) are to be allocated like that:Where
sizeof(struct data_array)
is the constant size of your struct excludingdata
and1000
is the desired array size. Of course changingdata
to be a pointer and allocating it seperately will also work, but that is something slightly different.As to the reason why you cannot convert
double*
todouble[]
, you may refer to this question that was asked before.As to solve the problem, changing
double data[];
todouble *data;
will work.New UPDATE:
You may either declare
data
to be an incomplete array (an array without specified dimension) or declare it to be a pointer. (An incomplete array inside a struct must be the last member and is called a flexible array member.)If you declare it to be an incomplete array, then the structure essentially contains the
length
element and as many array elements as you allocate for it. You must allocate it with the base size of the structure plus space for all the elements, as with:However, you should not return a structure allocated in this way, because there is no way to return the extra elements of the flexible array—the return type of a function would include only the base size of the structure. However, you could return a pointer to the structure. So, you could return
b
but not*b
.If you declare
data
to be a pointer, then you create the structure and separately allocate space fordata
to point to, as with:Here are code samples. First, with a flexible array member:
Or with a pointer: