2011-10-04 129 views
6

我已經創建了一個代碼塊,就像這樣。何時會釋放內存?

proc() 
{ 
    Z* z = new Z(); 
} 

現在在方法proc中聲明的指針只有proc纔會有作用域。我想問什麼時候z的DTOR將被自動調用。無論何時控件從方法proc出來或當我的應用程序關閉時。

回答

1

DTOR不會自動調用。你應該使用「刪除」關鍵字。

1

Z的析構函數將不會被調用,除非你把這樣一行在你的代碼:

delete z; 
17

析構函數將根本不會被調用。*z使用的內存將被泄漏,直到應用程序關閉(此時操作系統將收回您的進程所使用的所有內存)。

爲避免泄漏,您必須在某個時間撥打delete,或者更好的方法是使用智能指針。

4

除非您通過zdelete,否則您將發生內存泄漏。

+0

在我已經聲明* z的代碼塊中,我完成了它,所以我可以在返回proc語句之前調用「delete z」。 –

+1

@Apoorva:如果您從不需要塊外的'* z',則不應該使用動態分配。正如James Kanze寫道的,只需使用'Z z;',當proc()返回時,對象將被銷燬。 – MSalters

12

這是內存泄漏。你可能應該擁有的是:

void 
proc() 
{ 
    Z z; 
} 

並跳過動態分配。如果一個對象的生命週期對應於其範圍 ,那麼您很少需要動態分配。

如果由於某種原因,您確實需要動態分配(例如,因爲多態性爲 ),那麼您應該使用某種智能指針; std::auto_ptr在這裏效果不錯,而且像scoped_ptr這樣的東西,如果你有 有它們,可能會更好。

+0

如果編譯器支持它,那麼最好使用unique_ptr,而你的scoped_ptr應該是類似的東西,但是不是標準的 – Geoffroy

+0

@Geoffroy'unique_ptr'只是一個更新的'auto_ptr';如果你知道你永遠不需要支持一個較老的編譯器,你可以使用它。 'scoped_ptr'具有更多有限的語義,因爲它不支持所有權的轉移。 –

1

當你使用新的對象在堆上分配時,堆在你程序中的所有函數之間共享,也就是說你可以鬆散地說,堆分配對象的作用域是你的程序,所以不用做刪除在對象上,它會存在,直到你的程序退出。

7

這是C++的基本原理之一。

動態分配

在你的情況,內存分配和隨之而來的構造函數調用的Z將發生在new

Z* z = new Z(); 

銷燬和內存釋放相反的一部分將發生在delete

delete z; 

但是由於你的代碼沒有它,內存釋放將永遠不會發生,再加上你將失去指針z,將來不會釋放該對象。 這是典型的內存泄漏。

宣言

在另一方面,如果你聲明的對象是這樣的:

Z z; 

內存分配和構造函數將被調用立即就在這裏,在申報點,當對象存在範圍已完成(即在函數結束時),析構函數將自動調用並釋放內存。

動態分配VS宣言

我不會進入什麼是好,什麼是不爭論,而是將提供摘自是下面鏈接的文章之一:

與將數據加載到程序數據段的聲明不同,動態分配會在程序STACK(專門分配給該程序的RAM區域)上創建新的可用空間。

FYI:Stack = Performance,但not always the best solution

參考

爲您的樂趣:tictactoe

+0

Java在Java中的基礎如何?你的意思是「C++和Java之間的區別」嗎? – Simon

+0

謝謝,更新。經過少量修改後,第一句話就不再有效了。 –