In the past whenever I needed to create an instance of a class I would use new to allocate it on the heap (except for stl classes, and math classes like vec3 and mat4).
However, I was just looking critically at some of my code and realized that technically I could just be making these classes on the stack instead. They're not very big, don't need to be modified outside of their current scope, etc. When I (occasionally) need to pass them to another function I can use a reference as easily as I could pass a pointer.
In the past I always defaulted to allocating on the heap, and only used the stack in certain cases, however now I'm wondering if it would have been better to default to allocating on the stack, and only use the heap when
Which also raises the question: how big a class is too big (roughly) to reasonably allocate on the stack? (assuming we're working on, at minimum, smartphones, and going up to high end desktops) Am I just worrying unnecessarily about stack size constraints? (probably, as long as we're not talking large arrays, and no class is going to be even close to a kilobyte)
Use the stack when your variable will not be used after the current function returns. Use the heap when the data in the variable is needed beyond the lifetime of the current function.
the values of local variables are stored on the stack unless the local variables are in an iterator block or are closed-over outer variables of an anonymous method or a lambda expression. In those cases the values of local variables are stored on the heap.
Because the data is added and removed in a last-in-first-out manner, stack-based memory allocation is very simple and typically much faster than heap-based memory allocation (also known as dynamic memory allocation) typically allocated via malloc .
Stack accesses local variables only while Heap allows you to access variables globally. Stack variables can't be resized whereas Heap variables can be resized. Stack memory is allocated in a contiguous block whereas Heap memory is allocated in any random order.
Your default behavior should be:
If the lifespan of the object is consistent with a specific scope
ie easily determined at compile time
then it should be an automatic storage duration object (stack like)
If the lifespan of the object is defined at runtime and extends beyond the current scope
Then it should be a a dynamic storage duration object (heap like)
Note: All dynamic storage duration objects should have their lifespan controlled by wrapping them in a an appropriate RAII class. Usually this means: For single objects a smart pointer, while multiple objects end up in a container.
I hate to see things defines as stack Vs heap. As it does not convey the real semantics of the situation.
int x; // its on the stack
struct X
{
int x; // Is this a stack or heap object?
} // It depends on its parent.
// But in both cases it is an automatic storage duration object.
// In both cases the lifespan's are well defined.
// The first is defined by the scope it is declared within.
// The second is defined by the lifespan of its parent.
You should be thinking in terms of automatic/dynamic 'storage duration' objects. This conveys the correct semantics of the language.
Note there are two other types of variable thus making four different types of variable. automatic/dynamic/static/thread 'storage duration' objects.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With