我试图通过转换以下两个不相关的类来理解对象的布局:
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;
};
要测试类,主要有以下代码:
int main()
{
A * pA = new A(5);
cout << pA << endl;
B * pB = (B *) pA;
pB->Show();
}
据我了解,
- 调用会成功
- B::_x 的值为 A::_a
- 在运行时,尝试访问 B::Show() 中的 B::_y 和 B::_z 应该会崩溃,因为该对象最初是 A 类型且大小为 4 字节,而编译器期望 _y 和 _z与大小为 12 字节的 B 对象的起始地址相距 4 和 8 字节的偏移量。
实际上,尽管使用 VS2010,在调试模式下,B::Show() 中的语句被打印并且 _y 和 _z 指向垃圾值,在发布模式下,语句被打印,并且 _y 和 _z 指向垃圾值,然后发生崩溃(仅有时:-()。
我预计我们应该在尝试访问 _y 和 _z 时立即观察到崩溃,因为它们必须指向未分配的内存,但这并没有发生。我知道这种情况应该属于“未定义行为”的范畴,但这种行为的可能解释是什么?