c++dynamic-memory-allocationdestructornew-operatordelete-operator

What came first, the destructor or delete() ? C++


Many answers on this site mentions that delete() calls destructor. But the sample code below seems to call delete() inside the destructor. What is the correct usage of delete() when object is initialized in stack and in heap?

Click for the source.

#include <iostream>
using namespace std;
 
class SmartPtr {
    int* ptr; // Actual pointer
public:
    // Constructor: Refer https:// www.geeksforgeeks.org/g-fact-93/
    // for use of explicit keyword
    explicit SmartPtr(int* p = NULL) { ptr = p; }
 
    // Destructor
    ~SmartPtr() { delete (ptr); }
 
    // Overloading dereferencing operator
    int& operator*() { return *ptr; }
};
 
int main()
{
    SmartPtr ptr(new int());
    *ptr = 20;
    cout << *ptr;
 
    // We don't need to call delete ptr: when the object
    // ptr goes out of scope, the destructor for it is automatically
    // called and destructor does delete ptr.
 
    return 0;
}

Solution

  • When the destructor SmartPtr gets the control

     ~SmartPtr() { delete (ptr); }
    

    its body is executed. Within the body there is used the operator delete that is executed. If the pointer ptr would point to an object of a class type then the destructor of the class would be in turn called before freeing the dynamically allocated memory for the object.

    Here is a demonstration program.

    #include <iostream>
    
    int main()
    {
        struct A
        {
            ~A() { std::cout << "A::~A() called\n"; }
        };
    
        struct B
        {
            B() : ptr( new A ) {};
            ~B()
            {
                std::cout << "B::~B() called\n";
                delete ptr;
            }
            A *ptr;
        };
    
        { 
            B b; 
        }
    
        std::cout << "That is all!\n";
    }
    

    The program output is

    B::~B() called
    A::~A() called
    That is all!
    

    If to remove within the destructor of the class B this statement

    delete ptr;
    

    then objects of the class B will produce memory leaks because dynamically allocated objects of the class A will not be destroyed and the occupied memory by them will not be freed.