2012-09-03 156 views
0

伴侶的雷告訴我,我有內存泄漏在此代碼C++內存泄漏固定

Base 
{ 
    public: 
     vector<Foo*> fooes; 
}; 

Derived : public Base 
{ 
    public: 

     Derived () 
     { 
      for (int i = 0 ; i < 10 ; i++) 
      { 
        this.fooes.push_back (new Foo()); 
      } 
     }; 

}; 

但他是一個非常忙碌的人,他也幫不了我,所以我問你,內存泄露?我該如何解決它? 據我所知,內存泄漏是,我不刪除對象,通過new Foo()創建的,所以我就可以在析構函數添加到Base,並明確fooes載體,對不對?

Base 
{ 
    public: 
     vector<Foo*> fooes; 
     ~Base () 
     { 
      this->fooes.clear(); 
     }; 

}; 

的問題是:

  1. 這是一個正確的內存泄漏修復?

  2. 在Derived的析構函數之前調用Base的析構函數嗎?

  3. 將同時刪除Base或我必須手動刪除類的所有成員fooes vertor被自動刪除?

+0

什麼是'Foo'?它是多態的嗎? (和不相關的:'Base'的析構函數應該是虛擬的) –

+2

你只是不應該使用啞指針的向量。要麼使用智能指針的矢量,要麼使用專門設計用來容納指針的集合。 (還有其他可怕的方式會失敗,如複製分配或複製結構。) –

+3

如果你或你的伴侶沒有時間,那麼你絕對不能使用裸指針和'new'。製作一個'std :: vector >',繼續繁忙的生活而不用擔心內存管理。 –

回答

7

1)這是一個正確的內存泄漏修復?

不,你必須遍歷元素並手動delete他們。

2)將立足的析構函數的派生,或不析構函數之前被調用?

否(假設您正在刪除Derived對象)。

3)在刪除Base時是否會自動刪除fooes矢量,或者我必須手動刪除該類的所有成員?

是&沒有。因爲它是自動管理的載體本身將被刪除,其成員不得:

~Base () 
{ 
    for (size_t i = 0 ; i < fooes.size() ; i++) 
    delete fooes[i]; 
}; 

你應該爲每一個newnew[]一個deletedelete[]分別。

一個更好的替代品,這一切都是使用智能指針。

+0

我們可以擴展向量類,以便它自己刪除?例如:vector_e.del_n_clear(); –

+0

@tuğrulbüyükışık標準容器不打算延長。 –

+0

@tuğrulbüyükışık你可以做的是做一個免費的函數,它將一個向量作爲參數並刪除它的項目:'template clearVector(T&vect){....};'。 –

3

您需要遍歷在矢量所有的指針和清除之前刪除它們。矢量將清除指針,但它不會清除他們指出,除非你自己做的內存或更改您的載體使用像一個shared_ptr。如果您的載體是對象的載體,那麼你就不會有內存泄漏,但由於該元素是已經通過new被分配的指針,你需要釋放內存 - 矢量不會自動爲您代勞。

+0

vector :: clear向量的所有元素被刪除:它們的析構函數被調用,然後它們被從vector容器中移除,留下容器大小爲0. – Kolyunya

+3

@Kolyunya動態分配對象的析構函數不是自動調用。 –

+1

@Kolyunya是的,它會銷燬指針,但是這不會釋放它們指向的內存 - 當不使用智能指針時必須手動完成 – mathematician1975

1

有一個在代碼示例沒有內存泄漏,只是一個類定義。如果一個程序創建了一個類型爲Derived的對象並將其銷燬,那麼可能(見下文)是內存泄漏。但是,如果一個程序創建一個類型爲Derived的對象,銷燬它所保存的所有Foo對象,然後刪除原始對象,則可能不會有內存泄漏。

內存泄漏很少能單獨分析;它們是整個程序的屬性。可以修改該類以刪除Foo對象,但這可能會強加一個新的設計約束,而這並非意圖。例如,Foo對象可能會將自己註冊到內部容器中,並要求所有這些對象都會一直存在,直到程序結束;根據需要,刪除Derived析構函數中的對象將是錯誤的。

現在,這大都是假設;我不會抱怨某人增強Derived的析構函數以刪除所有Foo對象 - 這可能是正確的做法。但總有一點疑問......