在C ++中删除STL映射中的已分配内存

时间:2013-05-06 14:03:29

标签: c++ map stl

我正在使用地图来存储一对(int和class),使用以下内容:

#include <iostream>
#include <utility>
#include <map>
using namespace std;

class abstractclass{...};

class derivedclass : public abstractclass{...};

typedef map<int,abstractclass*> dBase;

int main(){
    dBase db;
    db.insert(pair<int,abstractclass*>(123,new derivedclass));
    db.insert(pair<int,abstractclass*>(124,new derivedclass));
}

我如何删除分配给它的内存? 我需要能够使用insert用户定义的次数,因此可以删除每个数据库条目的方法,谢谢!

如果我能这样做而不使用也很有用的内存分配

3 个答案:

答案 0 :(得分:10)

由于您的类层次结构,您显然无法在abstractclass中按值存储map个对象,或者您遇到the infamous object slicing problem

解决此问题的常用方法是使用智能指针,例如。 std::unique_ptrstd::shared_ptr(C ++ 11,对于C ++ 03 从不在容器中使用 std::auto_ptr,因为它已损坏,但您可以安全地使用而是boost智能指针。)

所以你的map类型会变成例如。 std::map<int, std::unique_ptr<abstractclass>>。 然后你不再需要打扰删除对象了,当它们从地图中删除时,智能指针会自动处理它。

另一个解决方案是自己delete所有项目(如@MarkB所说)但这很容易出错,因此在可能的情况下通常会选择智能指针。

答案 1 :(得分:4)

只要您的abstractclass具有虚拟析构函数,您就可以简单地遍历容器中的所有项目以及delete项目的second组件以释放内存。有多种方法可以做到这一点:例如for循环,或for_each带有functor或lambda。

编辑: 经过进一步审核后,地图似乎拥有所有权,如果您使用map shared_ptr(来自boost或C ++),您的生活将会更轻松 11),或使用boost::ptr_map代替。然后您根本不必担心清理地图 - 您只需使用db.clear();即可自动清理所有项目。这些容器中的任何一个也有助于在插入重复项时管理内存。

答案 2 :(得分:3)

您可以在容器中使用智能指针:

#include <iostream>
#include <utility>
#include <map>
#include <memory>
using namespace std;

class abstractclass{...};

class derivedclass : public abstractclass{...};

typedef map<int,shared_ptr<abstractclass>> dBase;

int main(){
    dBase db;
    shared_ptr<abstractclass> ptr1(new derivedclass);
    shared_ptr<abstractclass> ptr2(new derivedclass);
    db.insert(pair<int,shared_ptr<abstractclass>>(123,ptr1));
    db.insert(pair<int,shared_ptr<abstractclass>>(124,ptr2));
}

共享指针会在这里给出一点开销,但优点是:

  1. 您不必关心删除对象 - 一旦地图被销毁,它们就会被删除。
  2. 您可以安全地创建新对象并尝试将其插入到地图中 - 如果插入失败(即使有异常),分配的对象将被安全销毁。
  3. 您可以插入一个空指针,稍后使用实际创建的值重置()(如果已存在具有此类键的值,则不实际创建对象)