删除std列表中的指针对象

时间:2014-06-12 23:19:30

标签: c++ list pointers c++11

我有std::listEntity个对象(屏幕上的对象)。在一个类EntityContainer中,我有一个指向不同实体的指针列表。当EntityContainer被破坏时,我希望该列表中的所有实体也被破坏。我怎么能这样做,同时避免导致删除列表成员的迭代器错误?

EntityContainer::~EntityContainer()
{
    // Destroy children
    int numChildren = children.size();
    for (int i = 0; i < numChildren; i++)
    {
        Entity*& child = children.back();
        delete child;
    }
}

上面导致std :: list :: clear()中的空指针访问冲突,它在EntityContainer的销毁期间被调用,因为它是该对象的成员变量。我相信这是因为我删除了列表中的对象,所以当然删除它们时会尝试访问它们。但是,我的问题是,如果我只是保留它,并允许clear()列表而不显式删除其中的对象,则永远不会调用它们的析构函数。我只能假设这是因为列表只破坏列表中的指针,而不是指针指向的对象。这主要是假设 - 我可能是错的。你会做什么?

4 个答案:

答案 0 :(得分:12)

假设children被定义为

std::list<Entity *> children;

您可以delete使用以下元素:

for(auto&& child : children) {
  delete child;
}
children.clear(); // not really needed since this code is in the destructor

此处没有任何问题可以使任何迭代器失效,因为您实际上并没有从list中删除任何元素,只会破坏列表元素指向的对象。在list语句完成后,for仍将包含相同数量的元素,只有它们将在该点指向无效内存。


但实际上,不要使用原始指针容器。将children定义为

std::list<std::unique_ptr<Entity>> children;

然后你可以摆脱析构函数的定义。

答案 1 :(得分:2)

你的循环不会在列表中的每个指针上调用delete。它只在最后一个指针上反复调用delete。这是您违反访问权限的原因。

delete无法从list删除任何内容,因为它对此一无所知。

您需要执行类似

的操作
for(auto itr = children.begin(); itr != children.end(); ++itr)
{
    Entity* child = *itr;
    delete child;
}

或者你喜欢的首选循环语法。

或者,您可以将其设为list std::unique_ptr<Entity>,以便在清除列表或删除条目时自动管理解除分配。

答案 2 :(得分:1)

std::list<Entity *>在销毁期间不会尝试访问任何指向的对象。

您的迭代删除代码显示错误。你应该做的只是循环遍历列表并删除所有内容:

for(Entity *ptr : children) {
    delete ptr;
}

然后离开列表进行清理(取消分配内部指针列表)。

答案 3 :(得分:0)

你的循环主要是因为这个

而给出错误
int numChildren = children.size();
for (int i = 0; i < numChildren; i++)
{
    Entity*& child = children.back(); // this always returns the last element on the last, it does not remove it.  You are trying to delete an already deleted pointer
    delete child;
}

就像上面提到的那样,尝试类似

的内容
for(auto itr = children.begin(); itr != children.end(); ++itr)
{
    Entity* child = *itr;
    delete child;
}