2

In the below code, when deleting a object of base class in destruct class, none of the destructors of any class are getting executed.What may be the reason? Which destructor is "delete obj" calling ?

#include <iostream>
using namespace std;
class base;

class destruct{
    public :
    destruct() {
        cout<<"Destruct Constructor called"<<endl;
    }

    void destructObj(base* obj) {
        delete obj;
    }

    ~destruct() {
        cout<<"Destruct Destructor called"<<endl;
    }
};

class base {
    int runs;
    public:

    base(){

        cout<<"Constructor called"<<endl;
    }

    ~base(){
        cout<<"destructor called"<<endl;
    }
};

int main() {
    base *obj = new base();
    destruct *desObj = new destruct();
    desObj->destructObj(obj);
    return 0;
}

I expected atleast one of the destructors running of any class. Please help me find out how the delete operator would be working in this case.

8
  • 1
    UB. Your destructor is not virtual. EDIT: ignore that, you're just deleting a base. base's destructor is only called, but if you were to pass desObj to destructObj it would be UB. Commented Jul 16, 2019 at 7:13
  • 1
    You never delete the desObj pointer, so that object won't be destructed. Commented Jul 16, 2019 at 7:14
  • 1
    And it doesn't matter when or where you delete the obj pointer. In another function or directly in main, it will still be deleted just the same. Perhaps the problem you have isn't replicated by the code you show? Is that really a proper minimal reproducible example that replicates the problem you have? What is the output of the program you show? What output did you expect? And please take some time to refresh how to ask good questions, as well as this question checklist. Commented Jul 16, 2019 at 7:16
  • 1
    @Neijwiert Despite the class name base there's no inheritance here. Commented Jul 16, 2019 at 7:36
  • 1
    Clang helpfully produces warning: deleting pointer to incomplete type 'base' may cause undefined behavior [-Wdelete-incomplete]. Commented Jul 16, 2019 at 7:57

2 Answers 2

3

The problem is that destruct::destructObj needs to see the definition of Base to know that there is a destructor to call, but all it has is a forward declaration.

Change your code to this and it works.

#include <iostream>
using namespace std;
class base;

class destruct{
    public :
    destruct() {
        cout<<"Destruct Constructor called"<<endl;
    }

    void destructObj(base* obj);

    ~destruct() {
        cout<<"Destruct Destructor called"<<endl;
    }
};

class base {
    int runs;
    public:

    base(){

        cout<<"Constructor called"<<endl;
    }

    ~base(){
        cout<<"destructor called"<<endl;
    }
};

// *** this function after base has been defined ***
inline void destruct::destructObj(base* obj) {
    delete obj;
}

int main() {
    base *obj = new base();
    destruct *desObj = new destruct();
    desObj->destructObj(obj);
    return 0;
}

Now this surprises me and I'm wondering if it's a g++ extension. I would have expected a compiler error when you tried to delete a pointer to a class where there is only a forward declaration. But I might be wrong.

UPDATE: apparently this (deleting a pointer to an incomplete class) is undefined behaviour, which I guess implies that it should compile. However your compiler really should be giving you a warning to tell you that there's a problem. Always pay attention to compiler warnings, and always compile with the maximum possible number of warnings enabled.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks john for the great explanation!!.
Does this mean the delete operator deallocated the memory of obj, But destructor of base class will not execute because of the reason you mentioned?
@anujbajpai That's clearly what's happening in your case. But all the C++ standard says is that the behaviour is undefined, which means literally anything could happen.
1

You are calling delete obj when obj is a pointer to an incomplete type. This is undefined behaviour (in practice this usually means that the destructor is not called, but anything could happen).

You need to move the definition of base up where it is visible to the function that calls delete.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.