Flexible Array Element in C Structure

Quote from section C-std 6.7.2.1,

struct s { int n; double d[]; }; 

This is a valid structure declaration. I am looking for a practical application of this syntax. To be precise, how is this design more or less powerful than storing the double * as the second element? Or is this another β€œdo-you-it-in-reusable” case?

Arpan

+5
c c99 flexible-array-member
Jun 15 '10 at 17:33
source share
4 answers

The C FAQ answers exactly this question. The quick answer is that this structure will include a double array inside the structure, not a pointer to an array outside the structure. As a quick example, you can use your structure, as in this example:

 struct s mystruct = malloc(sizeof(struct s) + 5 * sizeof(double)); sn = 12; sd[0] = 4.0; sd[1] = 5.0; sd[2] = 6.0; sd[3] = 7.0; sd[4] = 8.0; 

And so on - the size of the array that interests you is included in the distribution, and then you can use it just like any array. Typically, this type contains size as part of the structure, since using the + tag to skip an array of type s will necessarily be complicated by this situation.

In your added question: β€œHow is this construction more or less powerful than saving the pointer as the second element?”, It is not more powerful as such, but you do not need to hold the pointer, so you would save at least as much space - as well when you copy the structure, you also copied the array, not the pointer to the array - sometimes there would be a subtle difference, but a different time is very important. "You-can-do-it-in-multiple-way" is probably a good explanation, but there are times when you specifically want one design or another.

+10
Jun 15 '10 at 17:36
source share

The main advantage is that the flexible member of the array allows you to allocate one block of memory for the array along with other data in the structure (with a pointer, you usually should have two separately allocated blocks).

It is also useful for data transmitted by many network protocols, where the incoming stream is defined identically - an integer that determines the length, followed by many units (usually bytes / octets) of data. You can (usually) use type-pun to overlay a structure with a flexible member of an array on a buffer filled with such data, and work with it directly, instead of analyzing it for parts and then working with parts separately.

+4
Jun 15 '10 at 17:52
source share

You can use it to add header fields to dynamically allocated arrays, the most common of which will be its size:

 struct int_array { size_t size; int values[]; }; struct int_array *foo = malloc(sizeof *foo + 42 * sizeof *foo->values); foo->size = 42; ... for(size_t i = 0; i < foo->size; ++i) foo->values[i] = i * i; 

You could achieve similar results by using the int * element instead and allocating the array separately, but it will be less efficient both in terms of memory (extra pointer, heap control for the second memory block) and runtime (extra indirectness, 2- e distribution).

+1
Jun 15 '10 at 17:41
source share

I saw that this was used on Windows for strings that are marked by their length. Character data is stored immediately after the length in memory, keeping everything together neatly.

 typedef struct { SIZE_T bytes; TCHAR chars[]; } tagged_string; 
0
Jun 15 '10 at 17:36
source share



All Articles