views:

217

answers:

6

What's a good policy for when to use "new" to make an instance of a class? I've been hobby programming C++ for a while but I'm still not for sure when is the best time to do this:

MyClass thing(param1, param2);

over this:

MyClass* thing;
thing = new MyClass(param1, param2);

Any advice?

+4  A: 
 MyClass thing(param1, param2); //memory for thing is allocated on the process stack(static allocation)

 MyClass* thing;
 thing = new MyClass(param1, param2); //memory is allocated dynamically on the heap(free store) for thing

The difference lies here:

 int main()
 { 
   {
    MyClass thing(param1, param2); //thing is local to the scope
   } //destructor called for thing
   //cannot access thing (thing doesn't exist)
 } 

 int main()
 {
   {
     MyClass* thing;
     thing = new MyClass(param1, param2);
   }
  //the object pointed to by thing still exists
   //Memory leak
 }  

For large objects you must allocate memory dynamically(use new) because the process stack has a limited size.

Prasoon Saurav
Well, you can't still access `thing` after the scope ends. :) It still exists though, and since there are no longer any pointers pointing to it, it can never be released.
GMan
@GMan: Yes, you are right. My post requires some minor corrections.
Prasoon Saurav
`thing` the MyClass* will no longer exist where you claim it does, because it was a local variable that went out of scope. The MyClass object -- that `thing` used to point to -- will persist, and this object is what causes the memory leak.
Larry Wang
@Kaestur: Edited. Damn! I need a cup of coffee. :-)
Prasoon Saurav
Not very helpful. It gives the impression that you should use `new` explicitly. Always hide it behind a RAII wrapper so it gets deleted when the wrapper goes out of scope.
jalf
+2  A: 

The rule of thumb is: if it works without new, don't use new.

David Titarenco
That's a bad idea. It could seem to work as you pass the pointer around, until the stack frame gets freed. Then suddenly you have a reference to nothingness. Debugging is hard enough without adding trial-and-error code to the mix.
Borealid
But there's no pointer involved in `MyClass thing(param1, param2);`. If you can use objects like you use an `int`, you should.
David Titarenco
Javier
+5  A: 

The first approach creates a local instance on the stack that goes away when the calling function exits. The second creates an instance that stays on the heap until (and if) you explicitly release it again. The choice depends on what kind of control and lifetime you want for your object.

Carl Smotricz
+2  A: 

In general: you don't need to use new if you plan to delete the object in the same scope. If the object is quite large, you may want to use new.
You may want to look into the difference between heap and stack memory if you want to know the details.

Larry Wang
+21  A: 

Design-wise, use automatic (stack) allocation as much as possible. Whenever you need to extend the lifetime of an object beyond a certain scope, then dynamically allocate it.

And even so, never dynamically allocate things raw. Always keep them wrapped into some sort of wrapper that implements Scope-Bound Resource Management (SBRM, first known under the dumb/awkward name Resource-Acquisition Is Initialization or RAII.) That is, dynamic allocations should be kept in automatic objects that will clean up automatically!

A good example of this is std::vector: you cannot leak the memory internal to a vector, because it's destructor is run in every scenario when memory should be free'd, and it will free it for you. auto_ptr is the first and only smart pointer available in the standard library, but it's pretty bad. Better is to use shared_ptr, or many of the other popular smart pointers available in Boost and/or TR1 and/or C++0x.

Performance-wise, objects allocated on the stack can be done so very quickly (the stack size is increased per-function-call, so all the required memory has been allocated up-front by a simple move of a pointer.) Contrarily, dynamic allocation generally requires much more time. It's quite possible to get speedy dynamic allocations with custom allocation schemes, but even the best will still be slower than stack allocation.

Occasionally, you might find you spend too much time copying objects around. In this case, it may be worth it to dynamically allocate it and merely move pointers around. However, please note I said "find". This kind of change is something you find by profiling and measuring, never guessing.

So: Automatic allocation when possible, dynamic allocation when needed.

GMan
+1 for the presice answer :-)
Prasoon Saurav
+1 for "only when necessary"
rubenvb
Dan
+1  A: 

First, ask yourself the question, does it make sense for the object to be copied when another function wants it?

If it makes sense to copy the object, your best bet is to create everything on the stack or as member variables and then just pass copies around when needed.

If it does not make sense to copy the object, you'll need to use new form so that you can safely pass the pointer to the object. You have to use a pointer (or reference) because as noted it does not make sense to copy the object.

There are two exceptions I'm aware of:

If you know the object isn't going to be used after the current function is finished, you can create the object on the stack so that it is deleted. Just make very sure nobody holds on to a pointer to it afterwards! (I rarely find this is the case, but it happens)

If the object is used internally by another class which itself shouldn't be copied around, you can just put it in as a member variable. Since the object it is in won't be copied, and its only for internal use that will be safe.

Winston Ewert