在std: vector中擦除,调试,释放

erase in std::vector, debug, release

本文关键字:调试 释放 擦除 std vector      更新时间:2023-10-16

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习语来避免整个问题:

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

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

现在,至于为什么它在Release模式下工作,在某些情况下,Release模式下std::vector<>的迭代器是一个指向动态分配数组的简单指针。当调用erase时,迭代器继续指向数组的相同元素,而数组的内容已经被erase函数移动。这是未定义的行为,特定于标准库实现,但非常常见。在任何情况下都不应该依赖可移植代码中的行为

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

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

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

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