I was wondering when should I allocate a class on the stack in C++? I have a strong background in Java and in Java all classes are allocated on the heap, using the new
keyword. In C++ I can pick between stack and heap allocation but now that smart pointers are introduced, it makes more sense to allocate everything that doesn't transfer ownership with std::unique_ptr
.
I can't really think of any cases, where it would be necessary or better to use stack allocation. Maybe for some kind of optimisation in embedded systems?
Stack space is mainly used for storing order of method execution and local variables. Stack always stored blocks in LIFO order whereas heap memory used dynamic allocation for allocating and deallocating memory blocks. Memory allocated to the heap lives until one of the following events occurs : Program terminated.
Memory in a C/C++/Java program can either be allocated on a stack or a heap. Prerequisite: Memory layout of C program. Stack Allocation: The allocation happens on contiguous blocks of memory.
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) e.g. C's malloc .
Unlike Java, C++ arrays can be allocated on the stack. Java arrays are a special type of object, hence they can only be dynamically allocated via "new" and therefore allocated on the heap.
Use automatic (stack) allocation whenever the function scope - or the scope of a control block such as a for
, while
, if
etc. inside the function - is a good match for the lifetime the object needs. That way, if the object owns/controls any resources, such as dynamically allocated memory, file handles etc. - they will be freed during the destructor call as that scope is left. (Not at some unpredictable later time when a garbage collector winds up).
Only use new
if there's a clear need, such as:
needing the object to live longer than the function scope,
to hand over ownership to some other code
to have a container of pointers to base classes that you can then process polymorphically (i.e. using virtual dispatch to derived-class function implementations), or
an especially large allocation that would eat up much of the stack (your OS/process will have "negotiated" a limit, usually in the 1-8+ megabyte range)
std::unique_ptr<>
to manage the dynamic memory, and ensure it is released no matter how you leave the scope: by return
, throw
, break
etc.. (You may also use a std::unique_ptr<>
data member in a class
/struct
to manage any memory the object owns.)Mathieu Van Nevel comments below about C++11 move semantics - the relevance is that if you have a small management object on the stack that controls a large amount of dynamically allocated (heap) memory, move semantics grant extra assurances and fine-grained control of when the management object hands over its resources to another management object owned by other code (often the caller, but potentially some other container/register of objects). This handover can avoid data on the heap being copied/duplicated even momentarily. Additionally, elision and return-value-optimisation often allow nominally automatic/stack-hosted variables to be constructed directly in some memory they're eventually being assigned/returned-to, rather than copied there later.
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