Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the cause of flexible array member not at end of struct error?

Tags:

c

malloc

struct

I am wondering why I keep getting error: flexible array member not at end of struct error when I call malloc. I have a struct with a variable length array, and I keep getting this error.

The struct is,

typedef struct {
  size_t N;
  double data[];
  int label[];
} s_col; 

and the call to malloc is,

col = malloc(sizeof(s_col) + lc * (sizeof(double) + sizeof(int)));

Is this the correct call to malloc?

like image 773
csta Avatar asked Jun 24 '12 19:06

csta


2 Answers

You can only have one flexible array member in a struct, and it must always be the last member of the struct. In other words, in this case you've gone wrong before you call malloc, to the point that there's really no way to call malloc correctly for this struct.

To do what you seem to want (arrays of the same number of data and label members), you could consider something like:

struct my_pair { 
    double data;
    int label;
};

typedef struct { 
   size_t N;
   struct my_pair data_label[];
};

Note that this is somewhat different though: instead of an array of doubles followed by an array of ints, it gives you an array of one double followed by one int, then the next double, next int, and so on. Whether this is close enough to the same or not will depend on how you're using the data (e.g., for passing to an external function that expects a contiguous array, you'll probably have to do things differently).

like image 178
Jerry Coffin Avatar answered Sep 21 '22 00:09

Jerry Coffin


Given a struct definition and a pointer to the start of a struct, it is necessary that the C compiler be able to access any member of the struct without having to access anything else. Since the location of each item within the structure is determined by the number and types of items preceding it, accessing any item requires that the number and types of all preceding items be known. In the particular case where the last item is an array, this poses no particular difficulty since accessing an item in an array requires knowing where it starts (which requires knowing the number and type of preceding items, rather than the number of items in the array itself), and the item index (which the compiler may assume to be smaller than the number of items for which space exists, without having to know anything about the array size). If a Flexible Array Member appeared anywhere other than at the end of a struct, though, the location of any items which followed it would depend upon the number of items in the array--something the compiler isn't going to know.

like image 40
supercat Avatar answered Sep 19 '22 00:09

supercat