Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Struct member [ array vs pointer ]

Tags:

c

What is the benefit of declaring a C structure member as in array of size 1 instead of a pointer :

struct {
  a_struct_t a_member[1];
  ...
}b_struct;

Thanks in advance

like image 362
Walidix Avatar asked Sep 19 '25 07:09

Walidix


2 Answers

In a typical case, a structure with a member that's declared as an array of one item will have that member as the last item in the struct. The intent is that the struct will be allocated dynamically. When it is allocated, the code will allocate space for as many items as you really want/need in that array:

struct X {
    time_t birthday;
    char name[1];
};

struct X *x = malloc(sizeof(*x) + 35);
x->birthday = mktime(&t);
strcpy(x->name, "no more than 35 characters");

This works particularly well for strings -- the character you've allocated in the struct gives you space for the NUL terminator, so when you do the allocation, the number of characters you allocate is exactly the strlen() of the string you're going to put there. For most other kinds of items, you normally want to subtract one from the allocation size (or just live with the allocated space being one item larger than is strictly necessary).

You can do (sort of) the same thing with a pointer, but it results in allocating the body of the struct separately from the item you refer to via the pointer. The good point is that (unlike the method above) more than one item can be allocated dynamically, where the method above only works for the last member of the struct.

like image 116
Jerry Coffin Avatar answered Sep 21 '25 22:09

Jerry Coffin


What you describe are two different things entirely. If you have a pointer as a member:

a_struct_t* a_member;

then it is simply a pointer. There is no memory allocated inside of the struct to hold an a_struct_t. If, on the other hand, you have an array of size 1:

a_struct_t a_member[1];

then your struct actually has an object of type a_struct_t inside of it. From a memory standpoint, it isn't much different from just putting an object of that type inside the struct:

a_struct_t a_member;

From a usage standpoint, an array requires indirection to access the one element (i.e., you need to use *a_member instead of a_member).

like image 26
James McNellis Avatar answered Sep 21 '25 21:09

James McNellis