I tried the following code on gcc 4.4.5.
If the member ‘data’ is not present, the code executes fine, but in its presence, it crashes. It also doesn’t crash when the derived class’ dtor is not virtual.
I’m aware that the behavior would be Undefined as listed in C++03 (5.3.5 / 3) in both the cases, but still could someone provide me with some explanation why does it crash in the latter case?
And yes, I know UB means that anything can happen, but still I’d like to know implementation-specific details.
#include<iostream>
using std::cout;
struct base{
int data;
base(){
cout << "ctor of base\n";
}
~base(){
cout << "dtor of base\n";
}
};
struct derived : base{
derived(){
cout << "ctor of derived\n";
}
virtual ~derived(){
cout << "dtor of derived\n";
}
};
int main(){
base *p = new derived;
delete p;
}
Assuming what happens on my system (gcc 4.6.0, linux x86_64) is the same as what happens on yours (it also crashes with
dataand runs without), the implementation detail is thatpdoes not point at the beginning of the memory block allocated for the object of typederived.As
valgrindtold me,You can see that for yourself if you print the values of the pointers:
And the reason for that is that object layout in gcc is {vtable, base, derived}
When base is empty, the size of {vtable, base, derived} and {base} happen to be the same because allocating an object of empty class occupies nonzero number of bytes, which happens to be equal in both cases.
When derived has no virtual functions, vtable is not present, the addresses are again the same and delete succeeds.