Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ stack vs heap allocation

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?

like image 301
AteszDude Avatar asked Apr 15 '16 11:04

AteszDude


People also ask

What is the difference between stack and heap allocation?

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.

Does C use heap or stack?

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.

Are allocations faster on stack or 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) e.g. C's malloc .

Are C arrays allocated on the stack?

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.


1 Answers

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)

    • if this is the only reason you're using dynamic allocation, and you do want the lifetime of the object tied to a scope in your function, you should use a local 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.

like image 140
Tony Delroy Avatar answered Oct 13 '22 22:10

Tony Delroy