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 data
and runs without), the implementation detail is that p
does not point at the beginning of the memory block allocated for the object of type derived
.
As valgrind
told me,
Address 0x595c048 is 8 bytes inside a block of size 16 alloc'd
You can see that for yourself if you print the values of the pointers:
derived * d = new derived;
std::cout << d << '\n';
base *p = d;
std::cout << p << '\n';
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.
the size of the two types does not match and the layout in your example should differ.
you are comparing pod types versus a type with a vtable (the layout and offsets are implementation defined). when the destructor is called, the address of implicit this is assumed to have the layout of base
, but this is actually derived
. what's executed is equivalent to writing to/reading from an invalid address.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With