繁体   English   中英

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

[英]erase in std::vector, debug, release

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%崩溃。

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

为什么会这样?

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

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

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

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

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

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

应该

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

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

现在,关于它为什么在Release模式下起作用的原因是,在某些情况下,Release模式下std::vector<>的迭代器是指向动态分配数组的简单指针。 当您调用擦除时,迭代器将继续指向阵列的同一元素,而erase功能已移动了阵列的内容。 这是未定义的行为,并且特定于标准库实现,但是非常常见。 在任何情况下,您都不应依赖可移植代码中的行为。

但是,在某些标准库实现中,“调试”模式迭代器执行检查,并且比简单的指针更为复杂。 这样,他们可以检测到您在做非法的事情,有意导致崩溃,从而可以识别错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM