我已經創建了一個代碼塊,就像這樣。何時會釋放內存?
proc()
{
Z* z = new Z();
}
現在在方法proc中聲明的指針只有proc纔會有作用域。我想問什麼時候z的DTOR將被自動調用。無論何時控件從方法proc出來或當我的應用程序關閉時。
我已經創建了一個代碼塊,就像這樣。何時會釋放內存?
proc()
{
Z* z = new Z();
}
現在在方法proc中聲明的指針只有proc纔會有作用域。我想問什麼時候z的DTOR將被自動調用。無論何時控件從方法proc出來或當我的應用程序關閉時。
DTOR不會自動調用。你應該使用「刪除」關鍵字。
Z的析構函數將不會被調用,除非你把這樣一行在你的代碼:
delete z;
析構函數將根本不會被調用。*z
使用的內存將被泄漏,直到應用程序關閉(此時操作系統將收回您的進程所使用的所有內存)。
爲避免泄漏,您必須在某個時間撥打delete
,或者更好的方法是使用智能指針。
除非您通過z
到delete
,否則您將發生內存泄漏。
這是內存泄漏。你可能應該擁有的是:
void
proc()
{
Z z;
}
並跳過動態分配。如果一個對象的生命週期對應於其範圍 ,那麼您很少需要動態分配。
如果由於某種原因,您確實需要動態分配(例如,因爲多態性爲 ),那麼您應該使用某種智能指針; std::auto_ptr
在這裏效果不錯,而且像scoped_ptr
這樣的東西,如果你有 有它們,可能會更好。
如果編譯器支持它,那麼最好使用unique_ptr,而你的scoped_ptr應該是類似的東西,但是不是標準的 – Geoffroy
@Geoffroy'unique_ptr'只是一個更新的'auto_ptr';如果你知道你永遠不需要支持一個較老的編譯器,你可以使用它。 'scoped_ptr'具有更多有限的語義,因爲它不支持所有權的轉移。 –
當你使用新的對象在堆上分配時,堆在你程序中的所有函數之間共享,也就是說你可以鬆散地說,堆分配對象的作用域是你的程序,所以不用做刪除在對象上,它會存在,直到你的程序退出。
這是C++的基本原理之一。
動態分配
在你的情況,內存分配和隨之而來的構造函數調用的Z
將發生在new
:
Z* z = new Z();
銷燬和內存釋放相反的一部分將發生在delete
:
delete z;
但是由於你的代碼沒有它,內存釋放將永遠不會發生,再加上你將失去指針z
,將來不會釋放該對象。 這是典型的內存泄漏。
宣言
在另一方面,如果你聲明的對象是這樣的:
Z z;
內存分配和構造函數將被調用立即就在這裏,在申報點,當對象存在範圍已完成(即在函數結束時),析構函數將自動調用並釋放內存。
動態分配VS宣言
我不會進入什麼是好,什麼是不爭論,而是將提供摘自是下面鏈接的文章之一:
與將數據加載到程序數據段的聲明不同,動態分配會在程序STACK(專門分配給該程序的RAM區域)上創建新的可用空間。
FYI:Stack = Performance,但not always the best solution。
參考
Java在Java中的基礎如何?你的意思是「C++和Java之間的區別」嗎? – Simon
謝謝,更新。經過少量修改後,第一句話就不再有效了。 –
在我已經聲明* z的代碼塊中,我完成了它,所以我可以在返回proc語句之前調用「delete z」。 –
@Apoorva:如果您從不需要塊外的'* z',則不應該使用動態分配。正如James Kanze寫道的,只需使用'Z z;',當proc()返回時,對象將被銷燬。 – MSalters