Reputation: 170
After reading some tutorials I am still unclear on some points about memory management in C++.
1. when a class declared with the new operator goes out of scope is its destructor called and memory freed? Is it necessary to call the delete operator to free the class' memory and have its destructor called?
class Test{};
void newTest(){
Test *t = new Test;
}
int main()
{
newTest();
return 0;
}
2. Are variables (such as a vector) declared with the new keyword freed when the class they reside within is destroyed? Do those variables have to be explicitly deleted in the class's destructor?
class Test{
vector<int> *vec;
public:
Test();
};
Test::Test(){
*vec = new vector<int>;
}
void newTest(){
Test t;
}
int main()
{
newTest();
return 0;
}
3. Same as question 2, but with normal variables declared on the stack. In the following example, is the vector vec deleted when t goes out of scope?
class Test{
vector<int> vec;
};
void newTest(){
Test t;
}
int main()
{
newTest();
return 0;
}
4. Finally, which is the better way to declare a vector in a class, normally (on the stack) or with the new keyword (on the heap)?
Upvotes: 4
Views: 577
Reputation: 264351
- when a class declared with the new operator goes out of scope is its destructor called and memory freed? Is it necessary to call the delete operator to free the class' memory and have its destructor called?
A variable is either an object or a pointer (A clas is not declared with a new pointer).
Objects are automatically destroyed when they go out of scope.
Pointers are NOT deleted automatically.
void newTest()
{
Test t; // t created here and automatically destroyed.
}
void newTest()
{
std::auto_ptr<Test> t(new Test()); // t created here and automatically destroyed.
// Which will call delete on the contained pointer.
}
The pointer you declare goes out of scope but the memory is destructor is not called and the memory is leaked. You would need to do it manually (or use one of the techniques I pointed out).
- Are variables (such as a vector) declared with the new keyword freed when the class they reside within is destroyed? Do those variables have to be explicitly deleted in the class's destructor?
You mean pointers initialized with new
rather then declared with the new keyword
No. You must manually call destroy in the destructor. But it is better not to have a pointer in the class. Rather declare a vector object inside the class then it will be automatically destroyed.
class Test
{
vector<int> vectorObject;
std::auto_ptr<vector<int> > vectorPtrInSmartPointer;
vector<int>* vectorRaw
public:
Test();
~Test();
private:
Test(Test const& copy);
Test& operator=(Test const& copy);
};
Test::Test()
: vectorPtrInSmartPointer(new vector<int>()) // Need to initialize the smart pointer.
, vectorRaw(new vector<int>) // Need to initialize the RAW pointer
{
// Note the vectorObject was automatically created.
}
Test::~Test()
{
delete vectorRaw; // Need to manually release the RAW pointer.
}
// Smart pointer and object auto released.
Note:
Because the class Test contains a RAW pointer (vector*) I had to manually disable the copy constructor Test::Test(Test const&)
and assignment operator Test& operator=(Test const&)
. This is to make sure the Rule of 3 is being followed.
- Same as question 2, but with normal variables declared on the stack. In the following example, is the vector vec deleted when t goes out of scope?
Yes.
- Finally, which is the better way to declare a vector in a class, normally (on the stack) or with the new keyword (on the heap)?
Calling it the stack/heap obscures the details (as a member may an automatic member of dynamically allocated object). Prefer to think of them as automatic variables
and dynamic variables
. The automatic variables
are autoamtically destroyed when their containing scope is destroyed. So for function variables this mean when you leave the function. For class members this means when the object is destroyed. The choice would be to prefer be to use automatic variables
(ie not to allocate with new).
Upvotes: 1
Reputation: 5005
You should prefer to say an object has dynamic storage instead of "being on the heap". Similarly, use "automatic storage" instead of "on the stack".
The former are actually used in the standard, while the latter are more colloquial.
If an object has automatic storage then the compiler will automatically call its destructor when the object goes out of scope (at the end of the containing block).
The memory allocated with new
needs to be explicitly released. The storage for the actual pointer will be reclaimed, but not the object it points to.
So, if you use new
you need to have a matching delete
. A new[]
needs to be matched by a delete[]
.
(A "smart pointer" quite useful, as it will help relieve you of having to keep track of the new
and delete
's. Look it up!).
Destroying a vector (either via delete if allocated with new, or when it leaves scope if auto) will call the destructor of its elements. This is why it should we the preferred way to held multiple objects.
Conclusion:
If possible try to use smart pointers or collections.
Otherwise, make sure you delete
what you new
. (And if you write a class, allocate in the constructor any dynamic members and delete them in the class' destructor.)
Upvotes: 1
Reputation: 96233
It sounds like you may come from a Java background, so things with new
work a bit differently in C++.
The memory allocated with new
must be explicitly destroyed with delete
. This example has a memory leak.
Similar to question 1, you must delete the memory in the class destructor to reclaim it.
In this case the vector will be destructed automatically.
Within a class, always prefer to store members by value (as opposed to with new) unless you have a specific reason to do otherwise. Just because it's stored by value within the class doesn't mean it's on the stack, it's in the same region of memory that the containing class occupies.
Finally note that in C++ you can use RAII to make memory management much less error prone. Take a look at shared_ptr, scoped_ptr, and unique_ptr for example. These all handle automatically freeing the new
ly allocated memory when appropriate.
Upvotes: 2
Reputation: 67195
new
is not automatically destroyed when your pointer goes out of scope. You need to explicitly delete
any such object.new
must be freed explicitly. Most well-written classes will do this for you in the destructor. If you are writing the class, make sure you clean up any memory the class uses.Upvotes: 2
Reputation: 12479
delete
the object.Upvotes: 2
Reputation: 11232
These two simple rules should answer all the questions:
delete
in your code as many as new
.Upvotes: 0