Sydney.Ka
Sydney.Ka

Reputation: 175

The difference between delete and the destructor when both called?

I'm quite confused about destructors in C++. For example, when we call delete in the code below, it calls first the destructor of Derived1 and then the destructor of Base, then what happens? What about the pointer dynamically allocated? Also, what happens if I call directly the destructor of Derived1 without delete or when I call them both?

#include <iostream>

using namespace std;

class Base
{
public:
    Base(){
        cout << "Base Constructor Called\n";
    }
    ~Base(){
        cout << "Base Destructor called\n";
    }
};

class Derived1: public Base
{
public:
    Derived1(){
        cout << "Derived constructor called\n";
    }
    ~Derived1(){
        cout << "Derived destructor called\n";
    }
};

int main()
{
    Derived1 *b = new Derived1();
    delete b;
}

Upvotes: 1

Views: 885

Answers (3)

user12450543
user12450543

Reputation:

Lifetime, or the availability/existence span of time:

  1. Object
    beginning from it's being declared and defined with/without object initialization in a scope, up to the running point (current IP as on low level) is exiting out of that scope, at which the destructors of the object is executed to restore back all of memory claimed and do other necessary things to maintaining

  2. Allocation memory request (asked to OS by new, malloc etc instruction)
    beginning from being requested by such instruction with the pointer created internally and returned as the only base reference, up to that pointer is referred again to restore the claimed memory portion by delete instruction
    but for object memory allocation it will automatically call its destructor

    a_class *p = new a_class(1,2,3);

    (1,2,3) is initialization of the object being referenced by p pointer

    So of course, as the pointer lifetime is the same as explained, if it's finished by exiting out of its scope before deleting is executed then the memory keeps reserved, spared and immutably living, made alive by OS will stuff up the memory resource and hence the understanding of memory leak famous meaning/term

Upvotes: 0

eerorika
eerorika

Reputation: 238281

when we call delete in the code below, it calls first the destructor of Derived1 and then the destructor of Base

Strictly speaking, delete destroys only the most derived object which is Derived1 in this case. It is the destructor of Derived1 that calls the destructors of its own subobjects such as Base.

then what happens?

A deallocation function will be called with the pointer value as an operand. The function will release the previously allocated memory, which ends the duration of the region of storage. That region may then be re-used for storing other dynamic objects created with a new expression.

what happens if I call directly the destructor of Derived1

Then the object will be destroyed. The destruction ends the lifetime of the object, and (because the class is not trivially destructible) invokes the destructor.

without delete

Then the memory allocation will not be released and cannot be used for further allocations. This is often considered to be a "memory leak".

what happens ... when I call them both?

Then the behaviour of the program will be undefined.

Upvotes: 4

walnut
walnut

Reputation: 22152

After calling the destructors of the object, as you noted in your question, the delete expression calls operator delete, a special function which deallocates memory, and operator delete frees the memory allocation that b points to and that was previously allocated by a call to operator new (which the new expression in your code called).

After deallocation happened (i.e. after operator delete returned), the pointer b becomes invalid and cannot be used anymore.

Calling the destructor directly ends the lifetime of the pointed-to object (and will also call the base and member destructors), but does not deallocate memory by a call to operator delete. You could reuse the memory that the object occupied and the pointer points to, to place a new object into it (with a so-called placement-new expression), but the object that you called the destructor on will not be usable anymore. Trying to use it will cause undefined behavior. (There are exceptions to this for class types with trivial destructor pre-C++20.)

Using the delete expression on the pointer after having called the (non-trivial) destructor causes undefined behavior, because delete calls the destructor again, but outside the object's lifetime, which was ended by the previous destructor call.

Calling the destructor after having called delete causes undefined behavior as well, because it would use an invalid pointer.

Upvotes: 4

Related Questions