铸件和物体布局

casting and object layout

本文关键字:布局      更新时间:2023-10-16

我试图通过强制转换以下两个不相关的类来理解对象的布局:

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;
};

要测试类,main有以下代码:

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::_6z应该崩溃,因为对象最初的类型是A,大小为4字节,而编译器期望_y和_z从大小为12字节的B对象的起始地址偏移4和8字节

实际上,尽管使用VS2010,在调试模式下,B::Show()中的语句会被打印出来,_y和_z指向垃圾值,在发布模式中,语句被打印出来,并且_y和_z指向垃圾值,然后出现崩溃(只是有时:-()。

我原以为我们应该在尝试访问_y和_z时立即观察到崩溃,因为它们一定指向未分配的内存,但这并没有发生。我知道这种情况应该属于"未定义行为"的范畴,但对这种行为的可能解释是什么?

未定义行为的行为是未定义的。根据定义。

我们可以推测为什么程序以不同的方式失败,但事实是它可能每天都在变化,或者运行到运行,或者构建到构建。

这个问题没有实际效果,忘了它!