在C++中,當你像這樣在堆上一個新的變量:通過刪除這樣釋放動態分配的內存
int* a = new int;
你可以告訴C++回收內存:
delete a;
但是,當程序關閉時,它是否會自動釋放分配了新內存的內存?
在C++中,當你像這樣在堆上一個新的變量:通過刪除這樣釋放動態分配的內存
int* a = new int;
你可以告訴C++回收內存:
delete a;
但是,當程序關閉時,它是否會自動釋放分配了新內存的內存?
是的,它會自動收回,但如果你打算廣泛寫一個巨大的程序使用堆,而不是叫delete
的任何地方,你一定快速耗盡堆內存,這會使您的程序崩潰。
因此,這是一個必須要與每一個new
匹配的delete
(或delete []
如果使用new []
)謹慎地管理你的內存和可用動態分配的數據,只要你不再需要上述變量。
當進程終止時,內存被OS收回。當然,在任何情況下,這個論點都不應該被用來不通過程序進行適當的內存管理。
此外,典型的程序要複雜得多,並且在運行時分配大塊內存,只需要很短的時間。如果你沒有釋放這些內存,你的程序將會使用越來越多的不再需要的內存。 – schnaader 2010-07-18 16:56:22
不,您有責任將其釋放。此外,a
必須是一個指針,所以它應該是:
int *a = new int;
delete a;
這excellent answer by Brian R. Bondy細節爲什麼它以釋放a
分配的內存很好的做法。
顯式調用 刪除,因爲你可能在析構函數中的一些代碼 要 執行是非常重要的。就像可能將一些數據 寫入日誌文件一樣。如果您讓操作系統免費爲您提供內存,那麼您的代碼將不會被執行。
當程序結束時,大部分操作系統都會釋放內存 。但是 這是一個很好的做法,自己釋放它 ,就像我上面說的OS 不會調用你的析構函數。
至於調用刪除一般情況下,是 你總是想打電話刪除或 否則你將不得不在 你的程序內存泄漏,這將導致新的 分配失敗。
當您的進程終止時,操作系統會重新控制進程正在使用的所有資源(包括內存)。然而,那當然不會導致C++的析構函數必然運行,所以它不是沒有明確釋放所述資源的靈丹妙藥(儘管這對於int
或其他類型的noop dtors當然不是問題; )。
沒有,當程序退出(「關」)的動態分配的內存留的是
編輯:
閱讀其他的答案,我應該更加確切。動態分配的對象的析構函數不會運行,但內存將被任何體面的操作系統收回。
PS:第一行應閱讀
int* a = new int;
啊,是的,因爲它是一個指針。謝謝。 – Zerg 2010-07-18 16:52:54
不要讓人們告訴你是的。 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
,可以說是最有用的智能指針,但還有很多其他的。
如果指向動態分配的內存的每個指針都在一個將會破壞的對象中(即不是另一個被動態分配的對象),並且該對象知道釋放內存,則該指針保證被釋放。這個問題甚至不應該成爲問題,因爲你永遠不應該泄漏。
執行很長時間的程序也應該刪除,否則它們將耗盡內存並導致問題。 – 2010-07-18 19:14:03
我幾乎不會說你必須「仔細管理你的記憶」。只需使用RAII容器即可完成。 – GManNickG 2010-07-18 20:07:09