Reputation: 4862
I understand that this may be construed as one of those "what's your preference" questions, but I really want to know why you would choose one of the following methods over the other.
Suppose you had a super complex class, such as:
class CDoSomthing {
public:
CDoSomthing::CDoSomthing(char *sUserName, char *sPassword)
{
//Do somthing...
}
CDoSomthing::~CDoSomthing()
{
//Do somthing...
}
};
How should I declare a local instance within a global function?
int main(void)
{
CDoSomthing *pDoSomthing = new CDoSomthing("UserName", "Password");
//Do somthing...
delete pDoSomthing;
}
-- or --
int main(void)
{
CDoSomthing DoSomthing("UserName", "Password");
//Do somthing...
return 0;
}
Upvotes: 11
Views: 3051
Reputation: 66661
In addition to what has been said so far, but there are additional performance considerations to be taken into account, particularly in memory-allocation-intensive applications:
new
will allocate memory from the heap. In the case of intense (extremely frequent) allocation and deallocation, you will be paying a high price in:
So, when you need objects for a brief (or scoped) period of time, definitely use the second approach (local variable, on the stack.) If you need to share data between threads, use new/malloc
(on one hand you have to, on the second hand these objects are typically long-lived enough so you pay essentially 0-cost vis-a-vis the heap manager.)
Upvotes: 6
Reputation: 75991
There are two main considerations when you declare a variable on the stack vs. in the heap - lifetime control and resource management.
Allocating on the stack works really well when you have tight control over the lifetime of the object. That means you are not going to pass a pointer or a reference of that object to code outside of the scope of the local function. This means, no out parameters, no COM calls, no new threads. Quite a lot of limitations, but you get the object cleaned up properly for you on normal or exceptional exit from the current scope (Though, you might want to read up on stack unwinding rules with virtual destructors). The biggest drawback of the stack allocation - the stack is usually limited to 4K or 8K, so you might want to be careful what you put on it.
Allocating on the heap on the other hand would require you to cleanup the instance manually. That also means that you have a lot of freedom how to control the lifetime of the instance. You need to do this in two scenarios: a) you are going to pass that object out of scope; or b) the object is too big and allocating it on the stack could cause stack overflow.
BTW, a nice compromise between these two is allocating the object on the heap and allocating a smart pointer to it on the stack. This ensures that you are not wasting precious stack memory, while still getting the automatic cleanup on scope exit.
Upvotes: 23
Reputation:
The biggest difference between the two is that the new initiates a pointer to the object.
By creating the object without new, the object initiated is stored on the stack. If it is initiated with new, it returns a pointer to the new object that has been created on the heap. It actually returns a memory address that points to the new object. When this happens, you need to memory manage the variable. When you are done using the variable, you would need to call delete on it to avoid a memory leak. Without the new operator, when the variable goes out of scope the memory will be freed automatically.
So if you need to pass the variable outside of the current scope, using new is more efficient. However, if you need to make a temporary variable, or something that will only be used temporarily, having the object on the stack is going to be better, since you don't have to worry about memory management.
Upvotes: 2
Reputation: 234404
The second form is the so called RAII (Resource Acquisition Is Initialization) pattern. It has many advantages over the first.
When use new
, you have to use delete
yourself, and guarantee it will always be deleted, even if an exception is thrown. You must guarantee all that yourself.
If you use the second form, when the variable goes out of scope, it is always cleaned up automatically. And if an exception is thrown, the stack unwinds and it is also cleaned up.
So, you should prefer RAII (the second option).
Upvotes: 14
Reputation: 308120
Prefer local variables, unless you need the object's lifetime to extend beyond the current block. (Local variables are the second option). It's just easier than worrying about memory management.
P.S. If you need a pointer, because you need it to pass to another function, just use the address-of operator:
SomeFunction(&DoSomthing);
Upvotes: 27
Reputation: 14084
Mark Ransom is right, also you'll need to instantiate with new
if you are going to pass the variable as a parameter to the CreateThread-esque function.
Upvotes: 0
Reputation: 14895
The second version will unwind the stack if an exception is thrown. The first will not. I don't see much difference otherwise.
Upvotes: 3