Structure members on heap versus stack

So I am creating a structure that currently needs a lot of memory. I hope to shorten it in the future, but for now this is what it is. Hence, I need to allocate some of its elements on the heap because I get a stack overflow if they are pushed onto the stack. And yes I have increased the stack size, but on the target platform I have so much.

In this case, would it be "better" to allocate each structure element on the heap, or put some on the stack and a lot of stuff on the heap? For example:

typedef struct my_structure_s{ 

   int bounds[2];
   int num_values;
   int* values;               //needs to be very large

} my_structure_t;

      

Vs:

typedef struct my_structure_s{ 

   int* bounds;
   int* num_values;
   int* values;

} my_structure_t;

      

I know that "better" is largely subjective and may well cause a riot here. So what are the pros and cons of both examples? What do you usually do? Why?

Also, goodbye things _s, _t ... I know some of you might find this in bad taste, but this is a convention for a legacy codebase it will be integrated into.

Thanks everyone!

+3


source to share


2 answers


Better to keep simple elements as direct values ​​and only allocate the array. Using the extra two pointers just slows down access without any benefit.

Another option to consider if you have C99 or C11 is to use Flexible Array Element (FAM).

You define your structure using the notation:

typedef struct my_structure_s
{ 
   int bounds[2];
   int num_values;
   int values[];
} my_structure_t;

      

You would allocate enough memory for a structure and an N-element array in values

just one operation using:

my_structure_t *np = malloc(sizeof(*np) + N * sizeof(np->values[0]));

      

This means that you only need to free one block of memory.

While searching you can find links to "struct hack". This designation is actually a standardized form of structural hacking.




In the comments, the discussion continued:

This is an interesting approach; however, I cannot guarantee that I will have C99.

If needed, you can use a version of the struct hack code that looks like this:

typedef struct my_structure_s
{
    int bounds[2];
    int num_values;
    int values[1];
} my_structure_t;

      

The rest of the code remains unchanged. This uses slightly more memory (4-8 bytes more) than the FAM solution and is not strictly supported by the standard , but was widely used before the C99 standard so it is unlikely that the compiler would invalidate such code.

Ok, but what about:

typedef struct my_structure_s
{
    int bounds[2];
    int num_values;
    int values[MAX_SIZE];
} my_structure_t;

      

And then: my_structure_t *the_structure = malloc(sizeof(my_structure_t));

Will this also give me a fixed block size on the heap? (Except here, my block size will be larger than needed in some cases, because I don't always get MAX_SIZE).

If there isn't too much wasted space on average, then a fixed size array in a structure is even simpler. It also means that if MAX_SIZE is not too large, you can allocate it on the stack or heap, whereas the FAM approach provides for dynamic (heap) allocation. The problem is whether there is enough wasted space of the problem and what do you do if MAX_SIZE is small in this case. Otherwise, this is the simplest approach; I just assumed you ruled that out already.

Note that each of the proposed solutions avoids pointers bounds

and num_values

proposed in option 2 in question.

+3


source


do the first. It's easier and less error prone (you have to remember to highlight and release more stuff in the second)



BTW is not that the first example won't push num_values ​​onto the stack. IT will go wherever you allocate structure, stack, bunch of static

0


source







All Articles