Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is derived class destructor not called in clang [duplicate]

I found this code on a web site

#include <iostream>

using namespace std;

struct Base
{
    Base() { cout << "Base" << " "; }
    virtual ~Base() { cout << "~Base" << endl; }

    int i;
};
struct Der : public Base
{
    Der() { cout << "Der" << endl; }
    virtual ~Der() { cout << "~Der" << " "; }

    int it[10]; // sizeof(Base) != sizeof(Der)
};

int main()
{
    Base *bp = new Der;
    Base *bq = new Der[5];

    delete    bp;
    delete [] bq;   // this causes runtime error
}

why does it crash?

like image 303
Ruggero Turra Avatar asked Oct 13 '11 13:10

Ruggero Turra


People also ask

Why derived class destructor is called first?

The derived class must be constructed after the base class so that the derived class constructor can refer to base class data. For the same reason, the derived class destructor must run before the base class destructor.

Do derived classes need a virtual destructor?

Note: in a derived class, if your base class has a virtual destructor, your own destructor is automatically virtual. You might need an explicitly defined destructor for other reasons, but there's no need to redeclare a destructor simply to make sure it is virtual.

What happens if destructor is not virtual?

Deleting a derived class object using a pointer of base class type that has a non-virtual destructor results in undefined behavior.


1 Answers

Base *bq = new Der[5];
delete [] bq;   // this causes runtime error

The reason is arrays are not treated polymorphically. Therefore, in the above code, the delete statement invokes undefined behaviour.

§5.3.5/3 C++03 says

In the first alternative (delete object), if the static type of the operand is different from its dynamic type, the static type shall be a base class of the operand’s dynamic type and the static type shall have a virtual destructor or the behavior is undefined. In the second alternative (delete array) if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined.

You're lucky that it gives runtime-error, and you got the opportunity to know a serious bug in your code, as soon as possible.

like image 193
Nawaz Avatar answered Sep 21 '22 16:09

Nawaz