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 en
As to the reason why you cannot convert double*
to double[]
, you may refer to this question that was asked before.
As to solve the problem, changing double data[];
to double *data;
will work.
New UPDATE:
double* b = malloc(sizeof(double) * 1000);
Few things:
1) change the struct defenation to:
struct data_array {
long length;
double* data;
^
};
2) This is how you should use malloc to allocate memory for your array:
a.data = malloc (length * sizeof(double));
EDIT
There are too many mistakes, just follow this code:
#include <stdio.h>
#include <stdlib.h>
struct data_array {
long length;
double* data;
};
struct data_array* test (int length) {
struct data_array* a;
a = malloc (sizeof (data_array));
a->data = malloc (length*sizeof(double));
a->length = length;
return a;
}
int main () {
data_array* x;
x = test (5);
for (int i=0; i<5; i++) {
x->data[i] = i+0.5;
}
for (int i=0; i<5; i++) {
printf ("%f\n" , x->data[i]);
}
}
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).
struct data_array * test(long length) {
struct data_array *a = calloc(1,sizeof(struct data_array) + length*sizeof(double));
a->length = length;
return a;
}
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:
struct data_array *b = malloc(sizeof *b + NumberOfElements * sizeof *b->data);
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 for data
to point to, as with:
struct data_array b;
b.length = NumberOfElements;
b.data = malloc(NumberOfElements * sizeof *b.data);
Here are code samples. First, with a flexible array member:
struct data_array
{
long length;
double data[];
};
struct data_array *test(size_t NumberOfElements)
{
struct data_array *b = malloc(sizeof *b + NumberOfElements * sizeof *b->data);
// Put code here to test the result of malloc.
b->length = NumberOfElements;
return b;
}
Or with a pointer:
struct data_array
{
long length;
double *data;
};
struct data_array test(size_t NumberOfElements)
{
struct data_array b = { NumberOfElements,
malloc(sizeof *b + NumberOfElements * sizeof *b->data) };
// Put code here to test the result of malloc.
return b;
}
I use gcc and I think may be this way is ok:
struct data_array {
long length;
double* data;
};
struct data_array* test (int length) {
struct data_array* a =(struct data_array *) malloc (sizeof (data_array));
a->data = malloc (length*sizeof(double));
a->length = length;
return a;
}
you are trying to change base address of the array at line
a.data = b;
It is not possible to modify the array base address, array base address is a constant pointer.