对于向量中的指针,我们应该在擦除之前还是之后删除?

Posted

技术标签:

【中文标题】对于向量中的指针,我们应该在擦除之前还是之后删除?【英文标题】:Should we delete before or after erase for an pointer in the vector? 【发布时间】:2010-09-17 06:24:21 【问题描述】:

我们应该在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???

【问题讨论】:

我相信你也有iter++,否则循环不会终止。 未说明的上下文是向量中的指针是被删除内存的唯一所有者。 【参考方案1】:

“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,我也会选择第二个版本:这样我就不会有向量中所有元素的变化。至少如果使用带有擦除的循环,反向迭代会更合适。 我同意,但是,我不确定 vector::erase 是否与 reverse_iterator 兼容(想通了很累) 您应该使用首选解决方案。它是 O(n) 而不是 O(n^2)【参考方案2】:

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

您还应该将擦除的返回值用于下一次循环迭代。

【讨论】:

一般来说很好,但您能告诉我们“您应该在删除项目之前删除它”背后的原因吗?我不明白为什么会这样。事实上,我认为反过来会更安全(即在多线程代码中)。缺点是您必须在调用擦除之前将指针的值暂时保留,否则您将无法删除它。我不认为它提供了很大的优势,所以不推荐它,但你的方式措辞你的答案看起来像删除之前是唯一的方法。 @n1ck:他在两个变体之间询问(即之前或之后)。我只是在回答这个问题。当然,您可以将指针移到临时位置,但是对于大多数应用程序来说,就地删除它们同样有效。 Harvey:当然,我只是说你的措辞可能不是最好的,因为它似乎暗示这是唯一的方法。我认为读者应该能够理解,但我只是想完全清楚,仅此而已。【参考方案3】:

另外,有没有什么情况我们不想在删除元素的同时删除它?

向量怎么可能知道其他人是否需要指向的对象?它怎么会知道指针存储在堆上呢?向量中完全可以有指向静态或自动对象的指针,甚至是悬空指针。

C++0x 允许你表达向量应该拥有指针:

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

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

如果您没有 C++0x 编译器,则可以改用 std::vector&lt;boost::shared_ptr&lt;foo&gt; &gt;boost::ptr_vector&lt;foo&gt;。现代编译器在std::tr1stdnamespace 中提供shared_ptr,如果你#include &lt;memory&gt;

【讨论】:

【参考方案4】:

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

std::vector<foo*> v1;
//...
while(!v1.empty())

    delete v1.back();
    v1.pop_back( );

顺便说一句 - 此方法不会使任何迭代器无效(仅在已删除的项目上)

【讨论】:

【参考方案5】:

执行erase 将使vector 迭代器无效。所以*iter 将调用未定义的行为。因此,您需要在erase 之后执行delete。此外,您不能在迭代 vectorerase 中的元素(由于同样的原因,iter 变得无效,因此 iter++ 无效)。在这种情况下,您可以从循环内部删除erase 调用,并在循环外部对向量执行clear

【讨论】:

以上是关于对于向量中的指针,我们应该在擦除之前还是之后删除?的主要内容,如果未能解决你的问题,请参考以下文章

C++ - 3-d 数据结构 - 我应该使用指针向量还是向量向量?

为啥 Python .readlines() 方法似乎在擦除文件?

网格擦除效果——类似宝剑大师

网格擦除效果——类似宝剑大师

如何释放向量中的指针?

从 Map 擦除后访问指针