2011-06-28 60 views
8

我有以下代碼,我想知道delete b在這裏是否有必要? 我的操作系統會自動清除分配的內存區域嗎?在析構函數中是否需要刪除?

class A 
{ 
    B *b; 

    A() 
    { 
     b = new B(); 
    } 

    ~A() 
    { 
     delete b; 
    } 
}; 

非常感謝。

+5

['A'還需要一個拷貝構造函數和賦值運算符](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-reeree)。 – GManNickG

回答

10

是的,你必須deletenew您擁有創建的每個對象。在這種情況下,它看起來像class A擁有class B的實例,並負責調用delete

使用智能指針來管理實例生存期會更好。另外請注意,您必須在class A中實施或禁止賦值運算符和複製構造函數,以防止淺拷貝會導致很大麻煩的對象。

1

它的寫作方式當然是必要的。但即使使用delete,班級也會因爲管理資源而受到嚴重破壞,但不會遵循the rule of three

也就是說,手動內存管理幾乎沒有任何理由 - 很少有。這可能是因爲你要麼只是有一個B對象作爲成員變量,或者你應該使用智能指針,就像QScopedPointer

struct A 
{ 
    QScopedPointer<B> b; 
    A() : b(new B()) { } 

    // No ~A() needed; when the A object is destroyed, QScopedPointer ensures 
    // that the B object pointed to by the member 'b' is destroyed and deleted. 
}; 

你要確保你有a good introductory C++ book這樣就可以了學習如何編寫正確的C++程序。

5

很可能您的操作系統將釋放分配的內存 - 但這是在程序退出時完成的。長時間運行的程序會遇到內存問題。

將動態指針用於動態全局對象始終是個好主意。這些會爲你做所有刪除的東西。

  • 的std :: auto_ptr的
  • 的boost :: shared_ptr的
  • 的boost :: scoped_ptr的
1

只有當過程結束這將清除該地區,但該地區仍保持分配所有的時間直到那時,這意味着memory leak

2

如果您撥打新電話,始終建議您進行相應的刪除。

至於操作系統刪除你的內存..是的,它會發生,但只有在整個過程終止後(即你的應用程序退出)。只有這樣操作系統才能回收所有內存和其他資源。

第三,只在必要時嘗試使用新/刪除。在你的情況下,你可以寫

class A 
{ 

B b; 

    A() {} 

    ~A() {} 

}; 

它會有同樣的效果,你避免了額外的動態內存分配。

0

b成員將被分配在堆上。確實,操作系統將釋放堆佔用的所有內存;但是這隻會發生一次:程序退出

所以,如果你沒有釋放分配的堆塊的時間,他們變得不使用(通常在某些對象的析構函數),你有冒險得到memory leak

因此,答案基本上是:,你必須手動調用delete,因爲內存不會被自動的儘快釋放(雖然智能指針將幫助你實現類似的東西)。

0

任何你分配的new你應該用delete免費,否則你的應用程序會有內存泄漏。

在大多數現代操作系統(當然人們通常在臺式計算機上運行的操作系統)中,流程使用的任何內容都會在流程結束時被清理,因此如果您忘記delete,那麼無論如何內存都將被釋放。但是你應該依靠這個。

很久以前,我在C編程了Amiga。它的操作系統比現在的操作系統要複雜得多。如果你要分配內存而不釋放它,那麼即使在過程結束後,它也會保持分配狀態,直到你關閉或重新啓動計算機。內存泄漏是一個更嚴重的問題。

1

資源管理不僅僅是釋放內存。是的,大多數平臺都會在流程結束時分配任何內存,並且內存足夠便宜,可能您一段時間都不會注意到。但文件b是否保持打開狀態,或者它將在其析構函數中解鎖的互斥鎖?在用完內存之前,您可能會遇到讓對象超出其有用性的問題。

0

1)長時間運行的應用程序會遇到問題,因爲操作系統只能在應用程序停止運行時回收內存。

2)delete b;也導致指向B實例的析構函數運行。否則它將永遠不會運行,因爲再也找不到它了。那個析構函數可能會做一些重要的事情。

相關問題