2012-08-10 158 views
0

我有這樣簡單的循環,通過基類的指針數組運行:GCC在調試模式下崩潰,在發佈模式下運行良好?

Object * objects[2]; 

objects[0] = new GreenObject; 
objects[1] = new RedObject; 
objects[2] = new BlueObject; 


for (int i = 0; i < 3; ++i) { 
    cout << i << " "; 
    objects[i]->info(); 
} 

在調試模式下,在循環的第三次迭代程序崩潰,輸出i,之後立即在調用info()方法。在發佈模式中不會發生這種情況,它正在運行。這不是該對象的問題,因爲即使我使用其他派生類,它也會鎖定。

GCC 4.4.0在Windows 7 64位

任何想法?

回答

8

這是(和for環)超出陣列的末尾:

objects[2] = new BlueObject; 

造成未定義的行爲。它在發佈中運行的事實只是(非)幸運的。未定義行爲的一個子集是行爲像你期望的那樣。

陣列索引從0運行到N - 1,其中N是陣列中元素的數量。在objects的情況下,有效索引僅爲01。改變objects的聲明:

Object * objects[3]; 
+0

是的,我知道該陣列比它需要的時間短,我的挫敗感是它在發佈模式下工作。 – dtech 2012-08-10 12:54:28

+1

它可能有幫助,如果你提到你知道它是在問題中的錯誤,說「它正在運行,因爲它應該」_暗示你認爲代碼是正確的。 – 2012-08-10 13:01:56

+0

您的程序的內存佈局可能因版本和調試設置而異。正如hmjd所說,這完全是未定義的行爲。 – Black 2012-08-10 13:02:55

6

訪問objects[2]是不確定的行爲。

這是一個常見的錯誤,期望編程錯誤總是導致崩潰或明顯的失敗。

未定義的行爲意味着任何事情都可能發生,包括出現在某些情況下工作。

如果你想要可預測,可重複的行爲,那麼你應該寫出正確的代碼。

相關問題