2013-03-20 79 views
0

這是作業。我的程序運行正常,但我無法擺脫內存泄漏。如何從嵌套的STL容器中刪除

我有一個Class對象。

我有一個類objectPtr,它有一個指向對象Class的指針。

我有...

typedef set<objectPtr> ObjectSet; 

我的對象存儲是這樣的:

map<string, ObjectSet*> myMap; 

當我嘗試通過數據結構來走,刪除對象(這就是我想我做...)我導致我的代碼崩潰。

for(map<string, ObjectSet*>::const_iterator it = myMap.begin(); it != myMap.end(); ++it) { 
    for(ObjectSet::const_iterator e = it->second->begin(); e != it->second->end(); ++e) 
     delete e->getPtr(); 
} 

什麼是正確的方法來做到這一點?

+0

什麼是'ItemSet'?什麼'getPtr'返回?如何定義'* e'?代碼不足以幫助我們。 – 2013-03-20 14:13:41

+1

張貼的代碼看起來很好,問題在別的地方。首先將指針存儲在STL容器中可能是一個錯誤。它擊敗了使用STL的許多優點。 – john 2013-03-20 14:13:50

+2

爲什麼你要將原始指針存儲在標準容器中有什麼特定的原因嗎?由於您已經遇到內存管理和所有權問題,這通常不是一個好主意。至少我會考慮將std :: shared_ptrs或std :: unique_ptrs存儲在容器中,如果您需要*多態行爲或實際值(如果您不需要)。 – 2013-03-20 14:15:11

回答

1

您可以在objectPtr的設計中使用基本的RAII原則。一般的概念是定義類objectPtr的析構函數,該函數調用存儲的指針object上的刪除。然後,您只需要在地圖上繞一圈來刪除指向ObjectSet的原始指針。因爲objectPtr作爲一個實例存儲(而不是指向實例的指針),所以當銷燬ObjectSet時,會自動調用析構函數。

另外,因爲您在for循環中調用delete,所以您可能需要非const轉發迭代器。

下面是一個例子:

class object 
{ 
    // ... interface details ... 
}; 

class objectPtr 
{ 
public: 
    objectPtr(object* p) : 
     ptr(p) 
    {} 

    ~objectPtr() 
    { 
     if (ptr) 
     delete ptr; 
    } 

public: 
    // ... interface details ... 

private: 
    object* ptr; 
}; 


typedef set<objectPtr> ObjectSet; 

map< string, ObjectSet* > myMap; 

for(map< string, ObjectSet* >::iterator it = myMap.begin(); it != myMap.end(); ++it) 
{ 
    ObjectSet* setPtr = it->second; 
    if (setPtr) 
     delete setPtr; // ObjectSet will call 'delete' for each instance of 
        // objectPtr, which through RAII, will automatically 
        // delete the referenced instance of object 
}