Destructor not being called when leaving scope
I am learning memory management in C++ and I don't get the why only some of the destructors are called when leaving scope. In the code below, only obj1 destructor is called when myfunc ends, not for the dynamically allocated obj2.
int myfunc (cl1 *oarg) {
cout << "myfunc called" << std::endl;
cl1 obj1(222,"NY");
cl1 *obj2;
obj2= new cl1;
oarg->disp();
obj2 -> ~cl1 ;
}
Here is the destructor I have :
cl1 :: ~cl1 () {
std::cout<< " cl1 destructor called"<<std::endl;
std::cout << this->data << std::endl;开发者_如何学编程 //just to identify the obj
delete [] str;
str = NULL ;
};
If you allocate a object using new
obj2= new cl1;
Then unless you call delete
on it, its destructor won't be called implicitly.
EDIT: As @David, meantions in comments, One may call destructor of an object explicitly but in my experience there is rarely a need to manually call the destructor unless one is using placement new version of new.
Variables on stack are implicitly cleaned up(by calling their destructors) when their scope ends.
Dynamically allocated objects are not implicitly cleaned, it is the responsibility of the user to clean them up explicitly calling delete
.
This is the very reason one should not use raw pointers but use smart pointers.
Dynamically allocated objects are your responsibility - you need to explicitly clean them up. Automatic objects (such as obj1
) are cleaned up when the scope exits, automatically. In this case, before the scope exits - explicitly call delete obj2
. NOTE: this line obj2 -> ~cl1
- does not do anything - the delete
will take care of triggering the destructor correctly.
obj1
is an object of type cl1
, with automatic storage duration (It is allocated on the stack, and its lifetime is determined by the scope it is in)
obj1
is an object of type cl1*
. That is, it is a pointer. The pointer also has automatic storage duration, but the object it points to does not. It points to a dynamically-allocated object in the free-store.
When you leave the scope, then the objects with automatic storage duration get destroyed. obj1
gets destroyed, calling your destructor. And obj2
also gets destroyed, but obj2
isn't of type cl1
, so it doesn't call cl1
's destructor. It is a pointer, and it does nothing special when it is destroyed.
Pointers don't own the objects they point to, and so they do nothing to ensure the pointed-to object gets destroyed or cleaned up. (If you want an "owning" pointer, that's what smart pointer classes are for)
Consider that you can easily have multiple pointers pointing to the same object.
If a pointer automatically deleted the object it pointed to, then that would lead to errors. An object pointed to by two different pointers would get deleted twice.
obj2 -> ~cl1 ;
Don't do this! Use delete obj2;
instead.
Addendum
What you were trying to do was to call the destructor explicitly. Your code does not do that. Your code is getting the address of the destructor and then dropping it into the bit bucket. Your code is a no-op. The correct way to explicitly call the destructor is obj2->~cli();
.
Explicitly calling the destructor is usually something you should not do.
What you should do is to delete the memory created by new
. The correct way to do that is to use the delete
operator. This automatically calls the destructor and releases the memory. The destructor does not release the memory. Failing to use delete results in a memory leak.
Destructors are called automatically when an object that was created on the stack goes out of scope.
With dynamically allocated objects, you need to call delete obj
. delete will automatically call your destructor for you.
You should use delete
for dynamically allocated objects:
delete obj2;
this calls the destructor and frees memory. You'll be much better off using smart pointers for managing such objects - they will call delete
for you even in case of exception being thrown between new
and delete
.
First of all you should use delete
operator to destrory an object and not call its destructor directtly. Secondly, by doing new
you are telling the compiler that you dont want to delete the object when it goes out of the scope. In such case you need to explictly fo delete objj2;
to delete the object.
Use std::unique_ptr or std::shared_ptr instead of raw pointer. It the best way to avoid memory leaks or double free.
That is the right way in modern C++.
int myfunc (cl1 *oarg)
{
cout << "myfunc called" << std::endl;
cl1 obj1(222,"NY");
std::unique_ptr<cl1> obj2( new cl1 );
oarg->disp();
}
精彩评论