Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flexible array member in C-structure

Quoting from the C-std section 6.7.2.1,

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

This is a valid structure declaration. I am looking for some practical use of this kind of syntax. To be precise, how is this construct any more or less powerful than keeping a double* as the 2nd element? Or is this another case of 'you-can-do-it-in-multiple-ways'?

Arpan

like image 812
Fanatic23 Avatar asked Jun 15 '10 17:06

Fanatic23


People also ask

What is flexible array member in C?

Flexible array members are a special type of array in which the last element of a structure with more than one named member has an incomplete array type; that is, the size of the array is not specified explicitly within the structure.

Is array a structure member in C?

An array within a structure is a member of the structure and can be accessed just as we access other elements of the structure.

Is an array flexible?

A flexible array is an array whose index bounds are determined at run time and may change during the lifetime of the array. Java arrays are flexible.

What is flexible C?

(Flexible array members are a C feature introduced in C99 whereby one can declare the last element to be an array of unspecified size. For example: ) struct header { size_t len; unsigned char data[]; }; c. arrays.

Can I declare an array in a struct C?

Declaration of Array of Structure in CIt may also include an array as its member. The struct keyword is used to create a structure. Here is an example: struct student { char name[50]; char class[100]; int roll_number; float marks[5]; };


2 Answers

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

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

And so on - the size of the array you care about is included in the allocation, and then you can use it just like any array. Normally such a type contains the size as part of the structure, since using the + trick to skip through an array of type s will be necessarily complicated by this situation.

To your added question 'how is this construct any more or less powerful than keeping a [pointer] as the 2nd element?', it's no more powerful per se, but you don't need to keep a pointer around, so you would save at least that much space - also when you are copying the structure, you would also copy the array, rather than a pointer to an array - a subtle difference sometimes, but very important other times. 'You-can-do-it-in-multiple-ways' is probably a good explanation, but there are cases where you would specifically want one design or the other.

like image 190
Carl Norum Avatar answered Sep 23 '22 10:09

Carl Norum


The primary advantage is that a flexible array member allows you to allocate a single block of memory for the array along with the other data in the struct (with a pointer, you'd typically end up with two separately allocated blocks).

It's also useful with data transmitted by quite a few network protocols, where the incoming stream is defined the same way -- an integer defining a length, followed by that many units (typically bytes/octets) of data. You can (typically) use a type-pun to overlay a struct with a flexible array member onto a buffer filled with such data, and work with it directly instead of having to parse it out into pieces and then work with the pieces individually.

like image 43
Jerry Coffin Avatar answered Sep 21 '22 10:09

Jerry Coffin