tags:

views:

128

answers:

7

Circle is a class, with public method GetDiameter(). What is the difference between the following 2 sets of code?

Qn1: Does Method 1 allocates memory for c on stack (hence no need free memory), while Method 2 allocates memory for c on heap (need manually free memory)?

Qn2: When should we use Method 1 or Method 2?

Method 1:

void Init()
{
 Circle c;
 c.GetDiameter();

 return;
}

Method 2:

void Init()
{
 Circle *c = new Circle();
 c->GetDiameter();

 return;
}
+2  A: 

Yes, Method 1 allocates on Stack and hence no need to free, where as Method 2 allocates on Heap which must be freed.

  1. Use Stack if you do not want the object after end of the function
  2. Use Heap if you wish to keep the object alive after the function's exit also(provided you retain the allocated address)
bjskishore123
Ah, but `Circle::operator new()` might be overridden to use `alloca()` to allocate stack memory. The instance would still need to be `deleted` though. I love C++ :)
Frédéric Hamidi
@Frédéric: I don't think that would actually be permitted. While it would compile, the results are almost certainly undefined since `operator new` is defined as performing allocation for objects that have dynamic storage duration. `alloca()` does not return a pointer to memory that has dynamic storage duration. However, a conforming `operator new` overload could always throw `bad_alloc`; that wouldn't be particularly useful, though...
James McNellis
What are those "permitted" or "undefined" or "conforming" things you're talking about? If it compiles, we'll ship it, pronto ;)
Frédéric Hamidi
+8  A: 

As a general rule for good coding practice, always use method 1 when possible. Method 2 should be used only if you need to store and/or share the pointer in different places. All objects used only locally in a method or class should be put in the stack.

Benoit Thiery
Minor note: exceptions are huge objects, for which sizeof(SomeClass) is something comparable with the whole stack size.
valdo
+6  A: 

Use method 2 when:

  • The lifetime of the object exceeds that of the scope of the function or
  • When you call some function that returns the pointer, i.e. you are creating the object from an abstract factory or similar.

The latter techique is commonly used to handle polymorphism, so the type you get might not actually be the type of the pointer but a class derived from it.

Whenever you need to delete the return value, it is best to handle it by wrapping it in a smart pointer or some other object where its destruction will happen "automatically".

If there is clean-up to do at the end of the function this should ideally be done through the use of automatic objects (like scoped_ptr or auto_ptr). This ensures that the clean-up happens even if the function terminates early (eg an exception gets thrown). This technique is called RAII - Resource Acquisition Is Initialisation.

CashCow
+1, also note that a new acronym is emerging SBRM (Scoped Bound Resources Management) synonym of RAII, but with a clearer name.
Matthieu M.
+1  A: 

Method 1: Memory allocated on stack. Method 2: Memory allocated on heap. + As a general rule, if you use call 'new' you must call 'delete' to deallocate the memory.

Prabhu
+2  A: 

one of the best discussions on heap vs. stack I have seen is here: heap vs. stack (scroll down to the middle of the discussion)

short summary:

  • stack: lifetime of object is controlled by compiler
  • heap: lifetime of object is controlled by the programmer
  • poseid
    A: 

    Stack

    • Limited and Fixed Size
    • Stricked Last in FirstOut object lifetime (limited normally to the enclosing function)

    Heap

    • Size normally only constrained by size of system memory
    • Manually managed object lifetime

    This means that for small object where only a short lifetime is ideal. The heap is needed for large objects or any object having a longer lifetime than the function in which is was created. The manual object lifetime does mean that you can develop memory leaks if you are not careful.

    doron
    A: 

    You haven't even began working with pointers and Method 2 has memory leak already.

    Grozz