在 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】:您的行为未定义,因为您使用了无效的迭代器(i
被 erase()
无效)。
使用Erase-remove Idiom 避免整个问题:
va.erase(std::remove(va.begin(), va.end(), 5), va.end());
【讨论】:
【参考方案2】:正如其他人指出的那样,崩溃是由于您在调用 va.erase()
后继续使用的无效迭代器造成的。
现在,至于它为何在发布模式下工作,是因为在某些情况下,发布模式下 std::vector<>
的迭代器是指向动态分配数组的简单指针。当您调用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 don
t 在释放模式下擦除时发生冲突。
@Boinred:因为您使用了无效的迭代器。未定义的行为。
换句话说,你很幸运。它不应该起作用。以上是关于在 std::vector 中擦除、调试、发布的主要内容,如果未能解决你的问题,请参考以下文章