2010-07-18 173 views
7

在C++中,當你像這樣在堆上一個新的變量:通過刪除這樣釋放動態分配的內存

int* a = new int; 

你可以告訴C++回收內存:

delete a; 

但是,當程序關閉時,它是否會自動釋放分配了新內存的內存?

回答

6

是的,它會自動收回,但如果你打算廣泛寫一個巨大的程序使用堆,而不是叫delete的任何地方,你一定快速耗盡堆內存,這會使您的程序崩潰。

因此,這是一個必須要與每一個new匹配的delete(或delete []如果使用new [])謹慎地管理你的內存和可用動態分配的數據,只要你不再需要上述變量。

+0

執行很長時間的程序也應該刪除,否則它們將耗盡內存並導致問題。 – 2010-07-18 19:14:03

+1

我幾乎不會說你必須「仔細管理你的記憶」。只需使用RAII容器即可完成。 – GManNickG 2010-07-18 20:07:09

3

當進程終止時,內存被OS收回。當然,在任何情況下,這個論點都不應該被用來不通過程序進行適當的內存管理。

+2

此外,典型的程序要複雜得多,並且在運行時分配大塊內存,只需要很短的時間。如果你沒有釋放這些內存,你的程序將會使用越來越多的不再需要的內存。 – schnaader 2010-07-18 16:56:22

1

不,您有責任將其釋放。此外,a必須是一個指針,所以它應該是:

int *a = new int; 
delete a; 

excellent answer by Brian R. Bondy細節爲什麼它以釋放a分配的內存很好的做法。

顯式調用 刪除,因爲你可能在析構函數中的一些代碼 要 執行是非常重要的。就像可能將一些數據 寫入日誌文件一樣。如果您讓操作系統免費爲您提供內存,那麼您的代碼將不會被執行。

當程序結束時,大部分操作系統都會釋放內存 。但是 這是一個很好的做法,自己釋放它 ,就像我上面說的OS 不會調用你的析構函數。

至於調用刪除一般情況下,是 你總是想打電話刪除或 否則你將不得不在 你的程序內存泄漏,這將導致新的 分配失敗。

+0

大多數操作系統都爲你做這項工作。 – tur1ng 2010-07-18 16:51:43

+1

@ tur1ng:確實如此,但是一些嵌入式操作系統希望你自己清理一下,不會爲你這樣做。在你真的是個壞主意之後,依靠操作系統清理。 – George 2010-07-18 16:58:50

0

當您的進程終止時,操作系統會重新控制進程正在使用的所有資源(包括內存)。然而,那當然不會導致C++的析構函數必然運行,所以它不是沒有明確釋放所述資源的靈丹妙藥(儘管這對於int或其他類型的noop dtors當然不是問題; )。

1

沒有,當程序退出(「關」)的動態分配的內存留的是

編輯:

閱讀其他的答案,我應該更加確切。動態分配的對象的析構函數不會運行,但內存將被任何體面的操作系統收回。

PS:第一行應閱讀

int* a = new int; 
+0

啊,是的,因爲它是一個指針。謝謝。 – Zerg 2010-07-18 16:52:54

2

不要讓人們告訴你是的。 C++沒有操作系統的概念,所以說「是的,操作系統會清理它」不再是在談論C++,而是在某些環境下運行的C++,這可能不是你的。

也就是說,如果你動態地分配一些東西,但從來沒有釋放它,你已經泄漏。一旦您撥打delete/delete[]就可以結束其使用期限。在一些操作系統的(和幾乎所有的桌面操作系統的),內存將被回收(所以其他程序可能會使用它)。但內存是不是相同的資源!操作系統可以釋放所有需要的內存,如果你有一些套接字連接關閉,某些文件完成寫入操作等,操作系統可能不會這樣做。不要讓資源泄漏很重要。我聽說過一些嵌入式平臺,它們甚至不會回收你沒有釋放的內存,導致泄漏,直到平臺重置。

而不是動態分配的東西原始(意思是你必須明確刪除它),將它們包裝到自動分配(堆棧分配)的容器;不這樣做被認爲是不好的做法,並使你的代碼非常混亂。

所以不要使用new T[N],請使用std::vector<T> v(N);。後者不會讓資源泄漏發生。請勿使用new T;,請使用smart_ptr p(new T);。智能指針將跟蹤對象並在知道更長時間使用時將其刪除。這稱爲作用域綁定資源管理(SBRM,也稱爲資源獲取即初始化,或RAII。)

請注意沒有單個「smart_ptr」。你必須選擇哪一個最好。目前的標準包括std::auto_ptr,但它很笨拙。 (它不能在標準容器中使用。)最好的選擇是使用Boost的智能指針部分,或者如果編譯器支持它,則使用TR1。然後你得到shared_ptr,可以說是最有用的智能指針,但還有很多其他的。

如果指向動態分配的內存的每個指針都在一個將會破壞的對象中(即不是另一個被動態分配的對象),並且該對象知道釋放內存,則該指針保證被釋放。這個問題甚至不應該成爲問題,因爲你永遠不應該泄漏。