2013-08-06 115 views
1

我試着鑄造以下兩個不相關的類來了解對象的佈局:鑄造和對象佈局

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 ::放映()語句被印刷和_y和_z指向垃圾值, 在釋放模式中,被印刷的聲明,和_y和_z指向垃圾值,然後出現崩潰(有時只有:-()

我希望在我們嘗試訪問_y和_z時應該已經觀察到崩潰,因爲它們必須指向未分配的內存,但這並沒有發生,我知道這種情況應該是在「未定義的行爲」的範圍之內,但這種行爲的可能解釋是什麼?

+0

沒有「應該崩潰」。行爲是未定義的。任何事情都可能發生。 –

+0

你自己回答:未定義的行爲意味着沒有保證 - 無論你做出什麼假設,他們都是錯誤的。沒有正確的假設。 – nijansen

+1

可能的解釋:用於分配A的內存來自堆大於A使用的4個字節的堆。 –

回答

0

T他未定義行爲的行爲是未定義的。根據定義。

我們可以推測爲什麼程序以不同的方式失敗,但事實是它可能會改變日常運行或運行運行或構建到構建。

0

這個問題沒有實際效果,忘了吧!