2012-07-02 30 views

回答

8

您需要釋放析構函數中的所有動態分配的內存。這不會自動完成。

你的類包含兩個指針,並且基本上無法控制這些指向的內容。事實上,這些可能指向你不能刪除,例如對象:

struct Foo {}; 
struct Bar { 
    Foo* f_; 
    Foo(Foo* f) : f(f_) {} 
}; 

int main() { 
    Foo f; 
    Bas b(&f); // b has a Foo ptr, but should it delete it? 
} 

所以你可以看到,它並沒有真正意義的指針數據成員被自動刪除。

作爲一般規則,如果你的班級管理資源,那麼你應該照顧複製建設和分配;這意味着,如果這對於類是有意義的,您應該禁用它們,或者爲它們提供實現,因爲編譯器生成的不起作用。有關此主題的詳細討論,請參閱the rule of three,並在計算器廣泛的討論:

如果不遵守這個規則,那麼默認的拷貝構造函數和賦值操作將生成一個淺拷貝,並且你將有多於一個的實例指向相同的動態分配的對象,這些對象將在銷燬後嘗試刪除。

您可以避免使用smart pointers手動刪除使用new創建的對象。在你的情況,其中類顯然擁有動態分配的對象,你應該看看C++ 11的std::unique_ptrboost::scoped_ptr

最後,你才能真正避免避免指針所有內存管理的問題都在一起,除非你真的需要。您可以將您的char*std::string例如更換:

class test{ 

    std::string p; 
    SomeClass someObject; 
    //test() : someObject() {} // default construction is probably OK... 
}; 

1。也就是說,它分配和釋放內存,或打開和關閉網絡連接,或者創建和銷燬互斥體等。

+1

他需要禁用複製語義或手動實施它們。 – Nawaz

+1

@Nawaz謝謝。添加了三個wiki的規則鏈接。 – juanchopanza

+0

可能值得建議你應該避免手動內存管理,如果可以的話,OP的代碼讓我聞到C和Java的混合。 – Arafangion

0

是的,你需要明確地釋放它們。指針作爲數據類型沒有任何析構函數。編譯器/執行環境沒有任何方法來猜測指針是否指向任何有意義或無意義的東西。即使該值是有意義的,它也可能指向某個靜態對象。或者它可以指向一個更大的對象的某個領域。編譯器沒有對指針進行任何自動清理。

3

是的,你必須free任何你mallocdelete一切你new

你也可以避免在你的班級中存儲指針。

class test{ 
public: 
    std::string p; 
    SomeClass  someObject; 
}; 
0

,如果你當test實例被破壞不回收它的內存泄露技術。您可以使用智能指針來避免在析構函數中顯式調用freedelete

struct Free { void operator() (void *p) const { free(p); } }; 

class test { 
    std::unique_ptr<char, Free> p; 
    std::unique_ptr<SomeClass> someObject; 
    test() : p(static_cast<char *>(malloc(1000)), 
       someObject(new SomeClass) 
    { //... 
    } 
    ~test() {} 
}; 

這使用智能指針的析構函數爲您執行清理操作。

如果test僅用作const全局實例,那麼實現清理並不重要,因爲直到執行結束,內存纔會被回收。但是總是實施清理是一個很好的做法,因爲它會使代碼現在正確,並且在將來可能會以不同的方式使用。

相關問題