11

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?

AteszDude
  • 161
  • 2
  • 15
  • 2
    Just an FYI a `std::unique_ptr` is a "stack" based object. BTW we call then automatic and dynamic objects as C++ has no concept of stack or heap. IMHO you want to use automatic objects whenever possible, – NathanOliver Apr 15 '16 at 12:00
  • 10
    You normally use the opposite principle: if dynamic allocation isn't necessary, you don't do it. Dynamic allocation by default is "premature pessimisation". – molbdnilo Apr 15 '16 at 12:02

2 Answers2

20

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.

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
  • that's a good summary. I recently reworked some code that was putting an array of very large objects in the stack. If you're not careful, you can run out of stack space in a larger program or one with deep recursion. – Kyle A Apr 15 '16 at 12:12
  • Some details about c++11 move semantic, and the answer will be perfect i think : upvote – Mathieu Van Nevel Apr 15 '16 at 12:21
  • Good summary, if you add when should I use std::unique_ptr instead of stack allocation I will give you the answer tick. – AteszDude Apr 16 '16 at 17:45
  • Didn't want to sound rude, I'm just always like this. – AteszDude Apr 17 '16 at 17:29
1

In large codebase we use stack allocation for simple struct objects while for more complex classes(that involve polymorphism, memory ownership etc) we always use dynamic allocation.

Khurram Shehzad
  • 261
  • 3
  • 12