tags:

views:

817

answers:

8

In C++, when is it best to use the stack? When is it best to use the heap?

+1  A: 

Use the heap for only allocating space for objects at runtime. If you know the size at compile time, use the stack. Instead of returning heap-allocated objects from a function, pass a buffer into the function for it to write to. That way the buffer can be allocated where the function is called as an array or other stack-based structure.

The fewer malloc() statements you have, the fewer chances for memory leaks.

Kyle Cronin
+9  A: 

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.

Eddie Deyo
There are ways to get around that though. Passing a buffer to a function that then writes data to it is a good way of having a function "return" dynamic data that lives on in a lower stack frame. It's less OO-like, but it's much more efficient.
Kyle Cronin
Size is also a consideration: anything over 1K on the stack should be considered carefully. Sometimes it's better to have a stack pointer to heap memory (together with 'Resource Acquisition is Initialization' idiom)
Arkadiy
+3  A: 

This question is related (though not really a dupe) to What and where are the stack and heap, which was asked a couple days ago.

pkaeding
A: 

The question is ill formed.

There are situations where you need the stack, others where you need the heap, others where you need the static storage, others where you need the const memory data, others where you need the free store.

The stack is fast, because allocation is just an "increment" over the SP, and all "allocation" is performed at invocation time of the function you are in. Heap (or free store) allocation/deallocation is more time expensive and error prone.

ugasoft
+5  A: 

As a rule of thumb, avoid creating huge objects on the stack.

  • Creating an object on the stack frees you from the burden of remembering to cleanup(read delete) the object. But creating too many objects on the stack will increase the chances of stack overflow.
  • If you use heap for the object, you get the as much memory the OS can provide, much larger than the stack, but then again you must make sure to free the memory when you are done. Also, creating too many objects too frequently in the heap will tend to fragment the memory, which in turn will affect the performance of your application.
nullDev
+2  A: 

Use the stack when the memory being used is strictly limited to the scope in which you are creating it. This is useful to avoid memory leaks because you know exactly where you want to use the memory, and you know when you no longer need it, so the memory will be cleaned up for you.

int main()
{ 
   if (...)
   {
      int i = 0;
   }
   // I know that i is no longer needed here, so declaring i in the above block 
   // limits the scope appropriately
}

The heap, however, is useful when your memory may be accessed outside of the scope of its creation and you do not wish to copy a stack variable. This can give you explicit control over how memory is allocated and deallocated.

Object* CreateObject();

int main()
{
    Object* obj = CreateObject();
    // I can continue to manipulate object and I decide when I'm done with it

    // ..
    // I'm done
    delete obj;
    // .. keep going if you wish
    return 0;
}

Object* CreateObject()
{
   Object* returnValue = new Object();
   // ... do a bunch of stuff to returnValue
   return returnValue;
   // Note the object created via new here doesn't go away, its passed back using 
   // a pointer
}

Obviously a common problem here is that you may forget to delete your object. This is called a memory leak. These problems are more prevalent as your program becomes less and less trivial where "ownership" (or who exactly is responsible for deleting things) becomes more difficult to define.

Common solutions in more managed languages (C#, Java) are to implement garbage collection so you don't have to think about deleting things. However, this means there's something in the background that runs aperiodically to check on your heap data. In a non-trivial program, this can become rather inefficient as a "garbage collection" thread pops up and chugs away, looking for data that should be deleted, while the rest of your program is blocked from executing.

In C++, the most common, and best (in my opinion) solution to dealing with memory leaks is to use a smart pointer. The most common of these is boost::shared_ptr which is (reference counted)

So to recreate the example above boost::shared_ptr CreateObject();

int main()
{
    boost::shared_ptr<Object> obj = CreateObject();
    // I can continue to manipulate object and I decide when I'm done with it

    // ..
    // I'm done, manually delete
    obj.reset(NULL);
    // .. keep going if you wish
    // here, if you forget to delete obj, the shared_ptr's destructor will note
    // that if no other shared_ptr's point to this memory 
    // it will automatically get deleted.
    return 0;
}

boost::shared_ptr<Object> CreateObject()
{
   boost::shared_ptr<Object> returnValue(new Object());
   // ... do a bunch of stuff to returnValue
   return returnValue;
   // Note the object created via new here doesn't go away, its passed back to 
   // the receiving shared_ptr, shared_ptr knows that another reference exists
   // to this memory, so it shouldn't delete the memory
}
Doug T.
+1  A: 

as a rule of thumb use the stack whenever you can. i.e. when the variable is never needed outside of that scope.

its faster, causes less fragmentation and is going to avoid the other overheads associated with calling malloc or new. allocating off of the stack is a couple of assembler operations, malloc or new is several hundred lines of code in an efficient implementation.

its never best to use the heap... just unavoidable. :)

jheriko
It's better than a couple of assembler operations - it's just one add or subtract (depending on which direction your stack grows).
Eclipse
+2  A: 

An exception to the rule mentioned above that you should generally use the stack for local variables that are not needed outside the scope of the function:

Recursive functions can exhaust the stack space if they allocate large local variables or if they are recursively invoked many times. If you have a recursive function that utilizes memory, it might be a good idea to use heap-based memory instead of stack-based memory.

Kluge