Destructor not being called when leaving scope

2019-02-11 07:01发布

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 ;

};

8条回答
女痞
2楼-- · 2019-02-11 07:24

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.

查看更多
Rolldiameter
3楼-- · 2019-02-11 07:24

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.

查看更多
姐就是有狂的资本
4楼-- · 2019-02-11 07:25

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.

查看更多
爷的心禁止访问
5楼-- · 2019-02-11 07:25

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();
}
查看更多
Emotional °昔
6楼-- · 2019-02-11 07:29

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.

查看更多
Fickle 薄情
7楼-- · 2019-02-11 07:35

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.

查看更多
登录 后发表回答