Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

One element array in struct

Why some struct uses a single element array, such as follows:

typedef struct Bitmapset
{
 int nwords;
 uint32 words[1];
} Bitmapset;

To make it convenient for latter dynamic allocation?

like image 790
Oxdeadbeef Avatar asked Dec 30 '10 02:12

Oxdeadbeef


People also ask

Can you have an array in a struct?

A structure may contain elements of different data types – int, char, float, double, etc. It may also contain an array as its member. Such an array is called an array within a structure.

How do you access an element in an array of structs?

Array elements are accessed using the Subscript variable, Similarly Structure members are accessed using dot [.] operator. Structure written inside another structure is called as nesting of two structures.

Can you have an array of structs in C?

An array of structres in C can be defined as the collection of multiple structures variables where each variable contains information about different entities. The array of structures in C are used to store information about multiple entities of different data types.

What is array within structure in C?

An array of structure in C programming is a collection of different datatype variables, grouped together under a single name. General form of structure declaration. The structural declaration is as follows − struct tagname{ datatype member1; datatype member2; datatype member n; };


2 Answers

In a word, yes.

Basically, the C99 way to do it is with an flexible array member:

uint32 words[];

Some pre-C99 compilers let you get away with:

uint32 words[0];

But the way to guarantee it to work across all compilers is:

uint32 words[1];

And then, no matter how it's declared, you can allocate the object with:

Bitmapset *allocate(int n)
{
    Bitmapset *p = malloc(offsetof(Bitmapset, words) + n * sizeof(p->words[0]));
    p->nwords = n;
    return p;
}

Though for best results you should use size_t instead of int.

like image 88
Chris Lutz Avatar answered Sep 21 '22 19:09

Chris Lutz


This is usually to allow idiomatic access to variable-sized struct instances. Considering your example, at runtime, you may have a Bitmapset that is laid out in memory like this:

-----------------
| nwords   |  3 |
| words[0] | 10 |
| words[1] | 20 |
| words[2] | 30 |
-----------------

So you end up with a runtime-variable number of uint32 "hanging off" the end of your struct, but accessible as if they're defined inline in the struct. This is basically (ab)using the fact that C does no runtime array-bounds checking to allow you to write code like:

for (int i = 0; i < myset.nwords; i++) {
  printf("%d\n", myset.words[i]);
}
like image 25
Will Robinson Avatar answered Sep 20 '22 19:09

Will Robinson