Are C structs allocated on the heap if they contain a pointer?

80 Views Asked by At

In my program I have a method that instantiates a structure and returns it something like this

struct A {
    int a;
    double * dblPtr;
    double ** dblMatrix;
}


struct A initStruct(int a) {
   struct A instance;

   instance.a = a;
   instance.dblPtr = malloc(sizeof(double));
   instance.dblMatrix = malloc(sizeof(double *) * 5);

   for (int i = 0; i < 5; i++) {
      instance.dblMatrix[i] = malloc(sizeof(double));
   }

   return instance
}

int main() {
   struct A a = initStruct(1);
   doOtherStuff(a);
   doMoreStuff(a);
   return 0
}

Does this struct get heap allocated or stack allocated? In my program I continue to use the struct after its returned so I presume it isn't stack allocated because then it would get wiped when I exit the initStruct scope right?

So Is it heap allocated? And why/how does that work?

Im expecting its heap allocated.

2

There are 2 best solutions below

0
Eric Postpischil On

Are C structs allocated on the heap if they contain a pointer?

No.

When you declare SomeType SomeName; inside a function, the program allocates space for an object of that type using automatically allocated storage (usually implemented with a stack), when program execution reaches that declaration. The type of SomeType is irrelevant.

Your struct A is a type that contains an int, a double *, and a double ** (which is a bad way to implement a two-dimensional matrix). Ultimately, those are just bytes. When it is allocated on the stack, it is simply enough bytes for an int, a double *, and a double **, including whatever padding the compiler lays out for the structure. The fact some of those bytes will be used as pointers is irrelevant to allocating space for the structure.

Further, you should not associate pointers with dynamically allocated memory (often implemented with a heap). A pointer can point to an object in statically allocated memory, an object in automatically allocated memory, an object in dynamically allocated memory, or an object in thread memory (and function pointer types can point to functions).

Does this struct get heap allocated or stack allocated?

When discussing C semantics, you should refer to these as dynamically allocated1 and automatically allocated. They are often implemented using a heap and a stack, but there are exceptions, and their semantics in C are as specified in the C standard, not governed by the properties of heaps or stacks.

Footnote

1 The C standard uses “allocated” as a name for the storage duration of dynamically allocated memory, but this is an unfortunate abridgment as the term is also used to refer to reserving memory of all storage durations.

0
NRagot On

The struct is allocated on the stack, not on the heap.

I see that your main source of confusion is that the struct is used outside the scope it was first initialized, which can be concerning when you know that the stack unwind after leaving a function. shouldn't the struct be lost ?

It works because return promises that this data is available for the caller scope. In a way, you could consider that the original was lost but you kept a copy.

But your intuition is good, because the following would be an issue indeed

struct A *initStruct(int a) {
   struct A instance;

   instance.a = a;
   instance.dblPtr = malloc(sizeof(double));
   instance.dblMatrix = malloc(sizeof(double *) * 5);

   for (int i = 0; i < 5; i++) {
      instance.dblMatrix[i] = malloc(sizeof(double));
   }

   return &instance
}

Returning a pointer to a an object that was allocated in the callee is dangerous, because only the pointer will be secured for the caller, not the struct it points to !