2013-03-20 27 views
0

假設我們有一個存放了一個指針成員對另一個對象的類。如果我在析構函數中刪除那個指針,我會得到一個錯誤(我理解爲什麼)。析構類,用於保存指向對象

我的問題是:有沒有可能克服,沒有內存泄漏?

這是我正在做的一個演示。的所有

class A { 
    public: 
    ~A() { cout<< "~A()" <<endl; } 
}; 

class B { 
    A *pA; 
    public: 
    B(A* pA) { 
     this->pA = pA; 
    } 
    ~B() { 
       delete pA; 
     cout<<"~B()"<<endl; 
    } 
}; 

int main() { 
    A a; 
    { 
     B b2(new A()); //deletes A, deletes B, no memory leaks 
    } 
    { 
     B b(&a); //deletes A, error. 
    } 

    return 0; 
} 

回答

2

首先不是內存泄漏,而是一個未定義的行爲,一個更嚴重的問題。嘗試從錯誤的區域釋放內存。
一個只應在相應new/new[]/malloc()使用delete/delete[]/free()

沒有充分的證據和架構獨立的方式,只是堅持良好的編程習慣。

可能不是完美的始終,但一個方法是重載newdelete,並持有std::map類似的數據結構。每當調用new時,將指針添加到它。在delete上,您可以檢查指針是否存在,如果分配類型爲newnew[]等。
肯定會影響您的性能,因此您需要將其保持在調試模式下。

2

你有兩個對象認爲他們擁有一個動態分配的對象並嘗試刪除它。解決的辦法是決定誰應該擁有的對象,並實現與相應的智能指針的幫助下,正確的複製/分配行爲:在所有

  1. AB處理動態分配的對象?不存在來自原始指針知道這種方式,這樣的設計必須被修改,以覆蓋一個外殼或其他。假設動態分配對象,則
  2. 每個對象都擁有自己的副本:實現三條規則中的AB,並且只有兩條刪除中的一條。您可以使用範圍的指針,以簡化內存管理(boost_scoped_ptr,或std::unique_ptr)。
  3. 唯一所有權:單個對象擁有該副本:使用std::unique_ptr。不允許複製和分配,允許移動複製和移動分配
  4. 共享所有權:沒有人/每個人都擁有該對象。當沒有人引用它,它被刪除:使用std::shared_ptr
+0

將智能指針知道該地址是從'new'或堆棧?我不這麼認爲。這種問題沒有萬無一失的方法。 OP也不會談論共享內存的多個對象。它一次只有一個,請查看「{}」範圍。 – iammilind 2013-03-20 07:17:51

+0

+1是你的最後一點有點自相矛盾。 「共享所有權」後面緊跟着「沒有人擁有對象」。 – dreamlax 2013-03-20 07:17:53

+0

@dreamlax如果每個人都擁有一些東西,那麼沒有人擁有它:-)但是我會試着重新修飾它以使其更清晰。 – juanchopanza 2013-03-20 07:19:40

1

你一定要告訴B,當它擁有指針,當它沒有。

添加額外的標誌能說明問題時

class B { 
    bool owner; 
    A *pA; 
    public: 
    B(A* pA, bool bOwner) : owner(bOwner) { 
     this->pA = pA; 
    } 
    ~B() { 
     if (owner) 
      delete pA; 
     cout<<"~B()"<<endl; 
    } 
}; 

int main() { 
    A a; 
    { 
     B b2(new A(), true); //deletes A, destroys B, no memory leaks 
    } 
    { 
     B b(&a, false); //destroys B, ok. 
    } 

    return 0; 
} 
+0

這段代碼如何處理以下情況:'B b(foo(),??);'其中'foo()'返回一個指針。 – iammilind 2013-03-20 07:21:59

+0

@iammilind當然,這取決於'b'是否擁有指針。如果是,則使用'B b(foo(),true)',如果不是'B b(foo(),false)'。 – 2013-03-20 07:24:40

+0

要過分簡單化......'A * foo(){static A a;返回(布爾)?新A:&a; }' – iammilind 2013-03-20 07:26:09

相關問題