我们应该在向量中删除指针之前或之后删除吗?

时间:2010-09-17 06:24:21

标签: c++ vector delete-operator

我们应该在erase之前还是之后删除。我的理解都是好的。这是对的吗?

此外,是否有任何情况我们不想在删除元素时删除它?我相信必须有,否则,erase将很乐意承担责任。

std::vector<foo*> bar;
...
for (vector<foo*>::iterator itr = bar.begin(); itr != bar.end(); itr++)
{
   delete (*itr);  //before OR
   bar.erase(itr);
   delete (*itr);  //after???
}

5 个答案:

答案 0 :(得分:10)

“itr”必须像这样使用;

for (vector<foo*>::iterator itr = bar.begin(); itr != bar.end(); )
{
   delete (*itr);
   itr = bar.erase(itr);
}

但是,我宁愿先删除所有元素,然后清除矢量;

for (vector<foo*>::iterator itr = bar.begin(); itr != bar.end(); ++itr)
   delete (*itr);
bar.clear();

答案 1 :(得分:4)

使用迭代器擦除元素会使迭代器无效。您应该在删除之前删除该项目。

您还应该使用擦除的返回值进行下一次循环迭代。

答案 2 :(得分:3)

  

此外,有没有我们不想在删除时删除元素?

矢量怎么可能知道是否还有其他人需要指向的对象?怎么可能知道这些蚂蚁存放在堆上?完全有可能在向量中指向静态或自动对象,甚至悬挂指针。

C ++ 0x允许您表示该向量应该拥有该对象:

std::vector<std::unique_ptr<foo>> vec;

现在您不必手动删除任何内容。通过擦除唯一指针,它们各自的指针也被删除。在现代C ++中,本机指针的容器非常罕见。

如果您没有C ++ 0x编译器,则可以使用std::vector<boost::shared_ptr<foo> >boost::ptr_vector<foo>代替。如果您shared_ptr,现代编译器也会在std::tr1std命名空间中提供#include <memory>

答案 3 :(得分:2)

擦除第一个元素的向量的性质导致整个数组向前移动,以减少此操作尝试以下:

std::vector<foo*> v1;
//...
while(!v1.empty())
{
    delete v1.back();
    v1.pop_back( );
}

顺便说一下 - 这个方法不会使任何迭代器失效(仅在擦除的项目上)

答案 4 :(得分:1)

执行erase将使vector迭代器无效。所以*iter将调用未定义的行为。因此,您需要在delete之后执行erase。另外,在erase进行迭代时,您无法vector iter中的元素(由于相同的原因,iter++变为无效,因此erase无效)。在这种情况下,您可以从循环内部移除clear调用,并在循环外执行向量的{{1}}。