C++ Should I allocate large structs on the heap or the stack?

Viewed 275

At what struct size should I consider allocating on the heap / free store using new keyword (or any other method of dynamic allocation) instead of on the stack?

10 bytes? 20 bytes? 200 bytes? 2KB? 2MB? Never?

Even if I wanted to pass it around by pointer, I could still take a reference from the stack variable. I understand that a stack variable will disappear at the end of the scope and dynamically allocated variables will not. I can deal with that either way, but so far I've not found any guidance for when to allocate dynamically. Sure, avoid stack overflow by not putting too much on the stack... but how much is too much?

Any guidance would be appreciated.

2 Answers

To actually answer the question, you'll need to know:

  • How big the stack is. This is often configurable at a compile-time, but may be capped by the target platform.

  • What is on the stack already. This knowledge is obtainable either by using deterministic call graph or by making decision actively, based on the current value of the stack pointer.

Without all of the above, any passive decision would be a gamble. Which also means that it's a gamble by default — indeed, in most cases we have to trust the compiler developers to understand how much of a stack space a "typical" program would need, and that our views on "typical" programs do align well and often.

In the long term, just like with any optimization problem, put your bets on measuring the overall performance and testing edge cases that may cause the stack overflow.

(Note. I probably should have searched before answering, but this question is essentially a duplicate of How much stack usage is too much?, nevertheless, here is my opinion on it.)

If you intend to keep a large buffer around for an extended period of time, then you should allocate it on the heap.

If you are in a recursive function, then allocating large buffers on the stack can quickly lead to problems.

Personally, I would keep buffers below ~4KiB on the stack and allocate larger buffers on the heap, unless you have a good overview of your program, and more specifically, how and where your functions are called.

That being said, if you constantly create and destroy buffers, consider putting them on the stack.

(If you are working on an embedded system, then that's a very different story.)

Related