在 std::vector 中擦除、调试、发布

Posted

技术标签:

【中文标题】在 std::vector 中擦除、调试、发布【英文标题】:erase in std::vector, debug, release 【发布时间】:2011-12-06 04:16:55 【问题描述】:

std::vector<int> va; // 和 push_back 1~100

std::vector<int>::iterator i = va.begin();
for(i; i != va.end(); )

    if((*i) == 5) va.erase(i);
    else i++

此代码在调试运行时 100% 崩溃。

但不要在发布运行时崩溃此代码。

为什么会这样?

这段代码有什么不同的调试和发布模式?

【问题讨论】:

【参考方案1】:

您的行为未定义,因为您使用了无效的迭代器(ierase() 无效)。

使用Erase-remove Idiom 避免整个问题:

va.erase(std::remove(va.begin(), va.end(), 5), va.end());

【讨论】:

【参考方案2】:

正如其他人指出的那样,崩溃是由于您在调用 va.erase() 后继续使用的无效迭代器造成的。

现在,至于它为何在发布模式下工作,是因为在某些情况下,发布模式下 std::vector&lt;&gt; 的迭代器是指向动态分配数组的简单指针。当您调用erase 时,迭代器继续指向数组的同一元素,而数组的内容已被erase 函数移动。这是未定义的行为和标准库实现特定的,但很常见。 在任何情况下都不应依赖可移植代码中的行为。

但是,在某些标准库实现中,调试模式迭代器执行检查并且比简单的指针更复杂。因此,他们可以检测到您正在做一些不合法的事情并故意导致崩溃,以便您识别您的错误。

【讨论】:

【参考方案3】:

vector::erase 返回一个新的迭代器,因为它使当前的迭代器无效。

if((*i) == 5) va.erase(i);

应该是

if((*i) == 5) i = va.erase(i);

【讨论】:

谢谢。您的答案。但我不t want solution, i want understand that why dont 在释放模式下擦除时发生冲突。 @Boinred:因为您使用了无效的迭代器。未定义的行为。 换句话说,你很幸运。它不应该起作用。

以上是关于在 std::vector 中擦除、调试、发布的主要内容,如果未能解决你的问题,请参考以下文章

在本机反应中擦除 AsyncStorage

从向量中擦除指针

在fabric js中擦除iText时显示光标线代替擦除的字符

击败从内存中擦除 PE

在单个链表线程中擦除和插入是不是安全?

为啥在Visual Studio中擦除位置之前矢量的c ++迭代器也无效?