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
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 calldelete obj2
. NOTE: this lineobj2 -> ~cl1
- does not do anything - thedelete
will take care of triggering the destructor correctly.You should use
delete
for dynamically allocated objects: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 betweennew
anddelete
.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++.
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.obj1
is an object of typecl1
, 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 typecl1*
. 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. Andobj2
also gets destroyed, butobj2
isn't of typecl1
, so it doesn't callcl1
'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.