爲了理解什麼是釋放記憶的意思,你必須先了解什麼分配記憶的意思。接下來是一個簡單的解釋。
存在內存。內存是你可以訪問的一大塊東西。但是由於它是全球性的,你需要一些方法來分解它。管理誰可以訪問哪些內存的某種方式。管理內存分配的系統之一被稱爲「堆」。
堆擁有一定數量的內存(一些由堆棧擁有,一些由靜態數據擁有,但現在不知道)。在程序開始時,堆表示您無權訪問堆擁有的內存。
new int
確實是兩倍。首先,它進入堆系統,並說:「我想要一塊適合存儲int
的內存。」它返回一個指向這個的指針:堆中的一塊,你可以安全地存儲和檢索類型爲int
的一個值。
你現在是一個int
值得記憶的自豪的擁有者。堆保證,只要遵循其規則,無論你放在那裏,都會保留下來,直到你明確地改變它爲止。這是你和全能堆之間的約。
另一件事new int
確實是用int
值初始化該堆的那塊。在這種情況下,它是默認初始化的,因爲沒有值被傳遞(new int(5)
將使用值5初始化它)。
從現在起,您可以合法地在這段內存中存儲一個int
。您可以檢索存儲在那裏的int
。而且你可以做另外一件事:告訴你堆完你的記憶。
當您撥打delete p
時,會發生兩件事。首先,p
被初始化。再次,因爲它是一個int
,沒有任何反應。如果這是一個類,它的析構函數會被調用。
但之後,delete
出來堆,並說,「嘿堆:記得這個指針,你給了我一個int
?我現在完成了。」堆系統可以做任何想做的事情。也許它會清除內存,就像一些堆在調試構建中所做的一樣。但是,在發佈版本中,內存可能不會被清除。
當然,爲什麼堆可以做任何想做的事情是因爲,你刪除了那個指針,你就會和堆進入一個新的協議。之前,您要求爲int
提供一塊內存,並且該堆有義務。你擁有這樣的記憶,並且堆可以保證只要你願意,它就是你的。你放在那裏的東西會留在那裏。
當你玩得很開心之後,你將它返回到了堆中。 。而這裏的合同來在當你說delete p
,爲任何對象p
,你說以下內容:
我莊嚴宣誓不會再碰這個內存地址!
現在,如果再次調用new int
,堆可能會將該內存地址返回給您。它可能會給你一個不同的。但是在new
和delete
之間的時間內,您只能訪問由堆分配的內存。
鑑於此,這是什麼意思?
delete p;
cout << *p << "\t" << p << "\n";
在C++的說法中,這被稱爲「未定義的行爲」。 C++規範有很多被聲明爲「未定義」的內容。當你觸發未定義的行爲任何事情都可能發生!*p
可能爲0. *p
可能是過去的值。做*p
可能崩潰你的程序。
C++規範是你和你的編譯器/計算機之間的契約。它說明你可以做什麼,並說明系統如何響應。 「未定義的行爲」是當你在合同中,當你做了一些C++規範說你不應該做的事情時發生的事情。在那一刻,任何事情都可能發生。
當您撥打delete p
時,您告訴系統您已使用p
完成。通過再次使用它,你是說謊到系統。因此,系統不再需要遵守任何規則,例如存儲要存儲的值。或繼續運行。或者不從你的鼻子產生惡魔。管他呢。
你打破了規則。你必須承擔後果。
因此不,delete p
不等於*p = 0
。後者只是意味着「將0設置到p
指向的內存中」。前者的意思是「我已經完成了使用p
,指向的內存,我不會再使用它,直到你告訴我我可以」。
那麼,它至少也會刪除指針所指向的數據,但我相信有人會很快得到更好的答案,說明「刪除」內存實際上意味着什麼。我懷疑它甚至可能不會記憶爲零,而只是允許再次分配空間。 – prelic 2012-01-31 01:36:51
使用一點批判性思維 - 「* p = 0」如何適用於例如'的std :: string'? – ildjarn 2012-01-31 01:37:33