[英]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%崩溃。
但是在发布运行时不要崩溃该代码。
为什么会这样?
此代码中的调试和发布模式有什么不同?
您有未定义的行为,因为您使用的是无效的迭代器( i
被erase()
无效)。
通过使用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.