cstructdynamic-allocation

Allocation of variables inside dynamically allocated structs


Suppose to have a struct that contains a pointer to an array and its size, like this one:

typedef struct {
    int * array;
    int arr_size;
}IntArray;

and want to have this inside another struct, it can be done in two ways:

typedef struct{
    IntArray ia;
    //other variables
}Base1;

typedef struct{
    IntArray * ia;
    //other variables
}Base2;

What happens when I dynamically allocate Base1 and Base2 (e.g Base1 b1 = (Base1 *)malloc(sizeof(Base1));) and why should I choose one way instead of the other?


Solution

    1. Nested structs' space exist as space in their parent struct, which means they don't need their own allocation (but they might still need their own initialization), whereas struct fields that are pointers need to be both allocated and freed when the parent object is initiated (this is a common cause of memory leaks in C because it does not have automatic object destructors like C++ does). Though if using a pointer you could point to another array/object that might exist on the stack (thus avoiding malloc/free) but then you might run into object lifetime bugs depending on the difference on scope and lifetimes of your objects.

    2. Nested structs exist in-place, so they cannot be shared by other instances. This may or may not be ideal (you could solve this with a template in C++, in C you'd have to settle for a hideous preprocessor macro).

    3. Because dynamically-allocated objects (such as your array and your Base2 type's nested ia member) exist in different locations in physical memory it means your code will not take advantage of spatial locality that the CPU's caches can take advantage of and you'll incur a double pointer dereference. So your code will run slower.

    Anyway: when in C, you should generally try to minimize pointer use.