Bemipefe
Bemipefe

Reputation: 1537

Dinamically vs Static memory allocation for a struct array

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 ?

Upvotes: 1

Views: 305

Answers (1)

schullzroll
schullzroll

Reputation: 167

The question is what happens when you try to free the wrapperStruct_p variable ?

Are you causing a memory leak ?

Most likely, but not necessary. The memory for the inner dynamic array is not freed, but you could still free it later if you saved the pointer address to some other variable.

Is the C memory management able to understand that the array of struct is made of 100 entries and not 1 ?

"C memory management" takes care of stack and heap allocations (the latter using systemcalls so maybe it's not really a "C memory management"), it doesn't do much else other than provide syntactic sugar on top of assembler (unlike garbage collected languages like Java or other).

C itself doesn't care about how many entries are somewhere and what part of memory you access (SEGFAULTS are the OS response to memory access violations)

What are the benefits of the first approach apart from not having to free the pointer inside the struct ?

If by "first approach" you mean stack allocated array, then it's mainly the fact that you do not need to allocate anything and the stack does it for you (drawback being that it stays allocated in the declared scope and you can't free up or increase the array space) then the constant allocation speed and assurance you'll get your 100 array items no matter the OS response (many realtime applications require maximum response times, therefore a heap allocation can be a really big slowdown causing problems).

If by "first approach" you mean using the wrapper struct, then I do not see any benefits other than the one you already stated.

I'd even suggest you not advocate/use this approach, since it is a really confusing technique that doesn't serve noticeable benefits (plus it allocates 1 space even though it may not be even used, but that's a detail)

The main goal is to write code that is easily understandable by other people. Machines and compilers can nowadays do wonders with code, so unless you are a compiler designer, standard library developer or machine level programmer for embedded systems, you should write simple to understand code.

Upvotes: 2

Related Questions