Кастинг и макет объекта

Я пытался понять расположение объекта, приведя следующие два несвязанных класса:

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::_y и B::_z в B::Show() должна завершиться сбоем, так как объект изначально имел тип A и размер 4 байта, где компилятор ожидал, что _y и _z иметь смещение в 4 и 8 байтов от начального адреса объекта B размером 12 байтов.

В действительности, хотя с VS2010, в режиме отладки операторы в B::Show() печатаются и _y и _z указывают на нежелательные значения, в режиме выпуска операторы печатаются, а _y и _z указывают на нежелательные значения, а затем происходит сбой (только иногда:-().

Я ожидал, что мы должны были наблюдать сбой, как только мы попытаемся получить доступ к _y и _z, поскольку они должны указывать на нераспределенную память, но этого не происходит. Я знаю, что это тот случай, когда предполагается, что он относится к сфере "неопределенного поведения", но все же, что является возможным объяснением этого поведения?

2 ответа

Поведение неопределенного поведения не определено. По определению.

Мы можем рассуждать о том, почему программа дает сбой по-разному, но правда в том, что она может меняться изо дня в день, или бегать к бегу, или строить для сборки.

Эта проблема не имеет никакого реального эффекта, забудьте об этом!

Другие вопросы по тегам