删除多个列表指向的数据?

时间:2012-12-29 03:50:12

标签: c++ pointers memory-management stdlist

我有一个可能最终出现在多个列表中的对象。

例如

std::list<object*> lista = new std::list<object*>();
std::list<object*> listb = new std::list<object*>();

object* obj = new object();
lista->push_front(obj);
listb->push_front(obj);

潜在地,有许多对象将以相同的方式在两个列表中结束。我意识到智能指针很容易做到,但我称之为受虐狂 - 我更愿意在没有它的情况下弄明白。

目前,我正在尝试这种技术:

td::list<object*>::iterator iter;
for(iter = lista->begin(); iter != lista->end(); iter++) {
    delete (*iter);
    *iter = 0;
}

std::list<object*>::iterator iterB;
for(iterB = listb->begin(); iterB != listb->end(); iterB++) {
    if(*iterB != 0) {
        delete (*iterB);
        *iter = 0;
    }
}

delete lista;
delete listb;

但它在运行时相当于delete lista;。希望有人能更聪明地指点指针可以帮助我。提前谢谢!

P.S。我正在运行Windows 7 / MinGW。

5 个答案:

答案 0 :(得分:3)

一个主要问题是你(显然,你没有提供完整的代码)delete一个对象两次:一次迭代列表A,一次迭代列表B。

主要有三种解决方案:

  • 使用像std::shared_ptr这样的引用计数智能指针 推荐的。你不想使用智能指针的陈述似乎是出于无知,而不是一些愚蠢的经理的要求。

  • 将节点保留在主列表中:
    delete节点只有当您知道它仍然存在的唯一列表时才是主列表。

  • 自己实施参考计数:
    最简单的方法是再次使用现有的库解决方案,例如boost::intrusive_ptr,但您所要做的就是在每个节点中精心维护引用计数。引用计数降至0时delete

第四种可能性是使用诸如Boehm收集器之类的垃圾收集器,但是代码需要被构造为支持它。或者至少那是我的印象。而且可能很难得到帮助,因为很少有C ++程序员使用这种方法(这表明它并非完全没有问题)。

答案 1 :(得分:1)

使用shared_ptr或拥有unique_ptr的主列表。

如果失败,请拥有一个拥有指针的主列表,并在清除后从中删除但不删除所有其他列表。

如果不这样做,请不要直接从列表中直接删除。而是insert你想要的指针进入std::set,并在删除之前从其他列表中删除它们(迭代并在集合中查找),或者累积你想要处理的所有指针然后质量从集合中删除它们。

这是按段落的粗略顺序。

答案 2 :(得分:0)

不确定为什么你真的不想使用shared_ptr。好适合自己。你怎么只创建一个本地shared_ptr?如果没有,则将列表加载到一个主列表中。清除两个子列表,并删除主列表中的每个元素以及清除主列表。

答案 3 :(得分:0)

在第

if(*iterB != 0) {

* iterB永远不会是0.所以你是双重删除。

答案 4 :(得分:0)

将计数器字段添加到object。默认初始化为0.添加到列表时添加+1。 -1从列表中删除。如果counter==0,请删除object

这不是shared_ptr的线程安全,但出于同样的原因它可以快得多。