I was trying to understand the layout of an object by casting following two unrelated classes:
class A
{
public:
A(int x):_a(x){}
private:
int _a;
};
class B
{
public:
void Show()
{
cout << "&_x = " << &_x << "," << " _x = " << _x << endl;
cout << "&_y = " << &_y << "," << " _y = " << _y << endl;
cout << "&_z = " << &_z << "," << " _z = " << _z << endl;
}
private:
int _x, _y, _z;
};
To test the classes the main has the following code:
int main()
{
A * pA = new A(5);
cout << pA << endl;
B * pB = (B *) pA;
pB->Show();
}
According to what I understand,
- The call will succeed
- B::_x will have value of A::_a
- At run time, trying to access B::_y and B::_z in B::Show() should crash, as the object was originally of type A and of size 4 bytes, where as the compiler would expect _y and _z to be at offsets of 4 and 8 bytes from the starting address of the B object which is of size 12 bytes.
In realty though with VS2010, in debug mode, the statements in B::Show() are printed and _y and _z point to junk values, in release mode, the statements are printed, and _y and _z point to junk values, and then there is a crash (only sometimes :-().
I expected that we should have observed a crash as soon as we try to access _y and _z as they must be pointing to unallocated memory, but that doesn't happen. I know this is case is supposed to be under the realm of "undefined behavior", but still what is the possible explanation for this behavior?