2012-10-07 29 views
2

在下面的代碼:在對象的動態數組上調用delete []不會釋放內存?

int main(int argc,char * argv[]){ 
    int * ptr; 
    ptr = 0; // tried also with NULL , nothing changes 
    ptr = new int[10]; // allocating 10 integers 
    ptr[2] = 5; 
    ptr[15] = 15; // this should cause error (seg fault) - but it doesn't 

    cout << ptr[2] << endl; 
    cout << ptr[15] << endl; // no error here 

    delete [] ptr; 

    cout << ptr[2] << endl; // prints the value 5 
    cout << ptr[15] << endl; // prints the value 15 
} 

執行的結果是:

5   
15   
5   
15   
  1. 索引號爲15的元素怎麼會存在,如果我只是分配10?
  2. 爲什麼指針在整個數組被釋放後仍然有值?

我試着用單分配這樣的刪除:

int * ptr; 
ptr = 0; 
ptr = new int; 
*ptr = 5; 
cout << *ptr << endl; 
delete ptr ; 
cout << *ptr << endl; 

的結果是正常的:

5   
0   

測試用gcc 4.7.2和gcc 4.1.2 fedora 17和另一個平臺(SLC5 - 基於linux的紅帽子),以確保它不依賴於編譯器。我在這裏做錯了什麼?

+0

我想,你應該閱讀接受的答案[這裏](http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope)(問題不同有一點,但是可以應用相同的論點) – Lol4t0

回答

9
  1. 超出預期數組大小的元素存在,因爲那裏的內存碰巧存在。用它做任何事情都是非法的,並導致黑暗的未知。

  2. 取消分配意味着內存不再分配給您。這並不意味着有人去那裏清理它。但是訪問你身邊的東西是非法的,會導致黑暗的未知。

+0

讓我補充一點,「黑暗的未知」實際上意味着「未定義的行爲」,這明確存在於C++標準的措辭中。 :) – vines

+1

是的;-)我會說「被稱爲未定義的行爲」,因爲沒有任何未定義提高了定義,足以使其更少不知道;-)我只是喜歡使用非陳詞濫調的措辭 - 它使人們重新解釋共同的概念。 –

+0

給1。這適用於我 - 關鍵是我的'用戶'不應該超過96內部的數量 - > getElement(int elementNum),而當我嘗試使用97時,它返回給我的值是意想不到的。所以,現在我確定我必須'讓它成爲不可能'給用戶 要2.這對我很有用,因爲我只關心進程「吃掉」的內存。我害怕我沒有清理它。 –

1

您正在訪問不屬於陣列存儲。它的運作是因爲純粹的運氣。如果程序沒有崩潰,這意味着你正在覆蓋屬於你自己的應用程序的部分內存,因此你在某個地方毀了某些東西,並且不能保證你的程序正常運行。

大多數情況下,您會遇到分段錯誤,因爲您訪問其他應用程序的內存。這一次,你只是'幸運'。或者因爲我稱之爲'不幸',因爲你不能立即從執行中判斷你的程序有內存錯誤。

+0

感謝這也是有道理的。我會嘗試使用耗費內存的程序「加載」系統,以便獲得我的'期望段故障'。我擔心我沒有按預期清理我的記憶。 –

1

取消引用已刪除的指針是C++標準定義的未定義行爲。而這只是 - 未定義的行爲。你可能會崩潰,你可能會得到0,你可能會得到以前的東西,或42。根據定義,在這一點上沒有「正常」的行爲。

相關問題