Reputation: 2065
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)
Upvotes: 12
Views: 5224
Reputation: 104698
When should a class be allocated on the stack instead of the heap?
Whenever possible and not a great inconvenience. There will be exceptions, but to answer your question as a general rule: When creating an instance, new
/new[]
should be typed less than one percent of the time.
a pointer is really needed (ie the lifetime of the object to outlast the scope of declaration)
Yes, in appropriate cases. Judging by your use of the heap described in the OP, this is likely going to be necessary far less often than you believe.
the class or array is too big for the stack
Yes, but that should not be much of a concern -- a class that large typically indicates that something is fundamentally wrong with your class. Client friendly classes might consider creating those huge, fixed sized arrays on the heap.
inheritance requires it (abstract base class/interface)
In some cases (e.g. where an abstract factory or deep clone of polymorphic type is present), but then it is the factory that creates the type, and the problem is often shifted away from your program's use of the stack before you can consider it.
something else?
No
The reasons:
Upvotes: 1
Reputation: 264391
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.
Upvotes: 8
Reputation: 23265
I prefer to allocate on the stack, for two reasons. First, all else being equal, it is faster than heap. Also, the deallocation happens automatically, I don't need to rememeber to delete
it (of course, there are auto_ptr
s and such to help with that).
a pointer is really needed
It is OK to pass a pointer to an object on the stack. Just make sure the user of that pointer does not access the object after its lifetime expires.
the class or array is too big for the stack
Only for really big things should this matter. You've probably got 1MB of stack, so you can put about 1000 1KB objects before there's a problem.
inheritance requires it
Why would it?
something else?
The lifetime required of the object is longer than the lifetime of the stack frame. This is the principal reason to allocate on the heap.
Upvotes: 5
Reputation: 7
You allocate on the heap only when you need to dynamically allocate the memory. Meaning you do not know how much you need to allocate at compile time. You allocate on the stack all other times
Upvotes: -2