If you want to allocate an array of struct you can do it statically by declaring something like
struct myStruct myStructArray[100];
or dinamically with something like
struct myStruct *myStructArray = calloc(100, sizeof(struct myStruct) );
but in this case you are responsible for freeing the memory.
In many applications and samples I found a mixed approach:
struct wrapperStruct
{
int myInt;
struct myStruct myStructArray[1];
};
Then the allocation is performed like this
int n = 100;
size_t memory_size = sizeof(struct wrapperStruct) + (n - 1) * sizeof(struct myStruct);
struct wrapperStruct *wrapperStruct_p = calloc(1, memory_size);
So (if I understood correctly) since the array is the last member of the struct and the field of a struct respect the same position in memory then you are "extending" the single entry array myStructArray with 99 entries.
This allow you to safety write something like wrapperStruct_p.myStructArray[44] without causing a buffer overflow and without having to create a dynamic allocated array of struct and then take care of the memory disposal at the end. So the alternative approach would be:
struct wrapperStruct
{
int myInt;
struct myStruct *myStructArray;
};
struct wrapperStruct *wrapperStruct_p = calloc(1, sizeof(struct wrapperStruct) );
wrapperStruct_p.myStructArray = calloc(100, sizeof(struct myStruct) )
The question is what happens when you try to free the wrapperStruct_p variable ?
Are you causing a memory leak ?
Is the C memory management able to understand that the array of struct is made of 100 entries and not 1 ?
What are the benefits of the first approach apart from not having to free the pointer inside the struct ?
struct myStruct myStructArray[1];is effectively faking a flexible array member, in a way that I wouldn't recommend doing (if it's legal at all). This answers "Is the C memory management able to understand that the array of struct is made of 100 entries and not 1?" in part, since using a FAM would make it clear that it's not just 1 element, and the number of elements is stored elsewhere. This is because, in C, the memory manager is the programmer.[]instead of[1]. (In GCC, you could use its extension[0]. That should not be used in new code.) If you use[1], the compiler may assume the array has only one element, regardless of how much you allocated, so optimization could transform an expression likep->member[complicated expression]top->member[0], since zero is the only defined value for the index of an array of one element (so it is a valid optimization to avoid calculating the expression), and that would break your program.struct myStruct *myStructArrayis equivalent tostruct myStruct myStructArray[]. I think you will end up with an uninitiated pointer in both cases. So if you need to allocate both with acallocormallocyou will have your memory in the heap. Is that correct ?struct myStruct *myStructArraycreates a pointer in the structure. To use it, you allocate memory for the structure, separate allocate memory for thestruct myStructdata, and set the pointer to point to that memory. When a member is declared asstruct myStruct myStructArray[], it tells the compiler that, when space is allocated for the structure, it may contain extra space forstruct myStructdata, and those extra elements will begin at the location in the structure wheremyStructArrayis.[]in place of*. I'm wondering what happens if you declare a variable likestruct wrapperStruct ws;. In this case the struct is stored in the stack and the stack should be expanded to store the array. I'm wondering if a limit can be hit. I mean do I need to allocatestruct wrapperStruct *wsso that the struct and the pointer are stored in the heap ?