Кастинг и макет объекта
Я пытался понять расположение объекта, приведя следующие два несвязанных класса:
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 ответа
Поведение неопределенного поведения не определено. По определению.
Мы можем рассуждать о том, почему программа дает сбой по-разному, но правда в том, что она может меняться изо дня в день, или бегать к бегу, или строить для сборки.
Эта проблема не имеет никакого реального эффекта, забудьте об этом!