2013-03-20 35 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 
}