2011-11-20 19 views
1

我對編程相對來說比較陌生,所以這可能聽起來像是一個愚蠢的問題,你給經驗豐富的專業人員在那裏。這裏所說:刪除內存並影響相關位置的數據

在C++中,當我使用數組delete運算符,我已經注意到,包含在已釋放內存位置的數據將被保留。例如:

int* testArray=new int[5]; 
testArray[3]=24; 
cout<<testArray[3]; //prints 24 
delete [] testArray; 
cout<<testArray[3]; // still prints 24 

隨後,我是對的假設,因爲testArray[3]仍然打印42,數據刪除存儲位置仍然保存?如果是這樣,這個概念是否適用於其他語言,是否有任何特別的原因呢?

不應該「釋放」存儲位置都有空數據,或者是「空閒內存」只是對於可以通過其他應用程序使用內存的代名詞,不管位置是否包含數據或不?

我注意到,當涉及到非陣列類型,如int,雙等解引用並輸出該已刪除變量打印0而非數據不是這種情況。我也有一個偷偷摸摸的懷疑,我可能會使用錯誤的語法來刪除testArray,這可能會讓這個問題更加愚蠢。儘管如此,我很想聽聽你的想法。

+0

您的刪除數組的語法是正確的。只要您在程序中創建了一個** Undefined Behavior(UB)**,就可以通過訪問一個'delete'd內存。由於UB沒有看到預期/假定產出。 –

+1

[你的聖經沒有被觸動。](http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope/6445794#6445794) –

回答

2

一旦通過調用delete釋放內存並嘗試再次訪問該地址處的內存,它就是未定義的行爲

該標準沒有要求編譯器在這方面做任何特殊的事情。它並不要求編譯器用0或某些特殊的幻數來標記取消分配的內存。它作爲編譯器的實現細節被忽略。一些編譯器實現會用一些特殊的幻數來標記這樣的內存,但這是留給每個編譯器實現的。

在你的情況下,數據仍然存在於解除分配的地址,因爲可能沒有其他內存需求需要重新利用內存並且編譯器沒有清除先前分配的內容(因爲它是不需要)。

但是,您不應該依賴於此,因爲這可能並非總是如此。它仍然是並將是一個未定義的行爲


編輯:在評論中回答Q.
delete運算符不返回任何值,所以你不能檢查返回狀態然而,標準保證了delete運營商將成功地做的工作。

C++ 03標準中的相關引用:
第§3.7.3.2節。4:

如果給予在標準庫解除分配功能的參數是一個指向不屬於空指針值(4.10),解除分配功能必須解除分配指針所引用的存儲,render-所有指向解除分配存儲的任何部分的指針均無效。

+0

這給我帶來了另一個問題。有沒有辦法確定刪除操作員是否完成了其工作? – Zubizaretta

+0

@Zubizaretta:更新了您的查詢答案。 –

2

的數據仍然存在,因爲當你免費的,它釋放它的分配表 - 該系統將是非常緩慢的,如果它的每個空閒時間()必須爲零的所有內存或刪除被調用。

這在任何語言中都是一樣的。

我覺得非數組類型被設定爲零,因爲他們實際上是靜態分配的,而不是動態分配。

+0

那會意味着程序永遠不會向OS提供任何內存(因爲它不會被訪問)。我不認爲這是所有語言的行爲。 – Patrick

+0

@Patrick Huh?我所說的「將它釋放到分配表中」的部分意味着它返回給操作系統 –

2

非POD數據將在析構函數中改變(可能在調試器中顯示爲空值)。

釋放的數據確實可用。

刪除後,您不能依賴未改變的數據。在相關說明中,調試malloc或運行時庫將頻繁地將數據重置爲特定簽名(0xdeadbeef,0xdcdcdcdc等),以便您可以輕鬆地在調試器中找到對已刪除內存的訪問。

+0

'non-POD'是什麼意思? – Speedy

+0

@Speedy:POD代表[Plain Old Data types](http://stackoverflow.com/questions/146452/what-are-pod-types-in-c)。 –