"Vector erase iterator outside range" 尝试删除之前保存的迭代器时

"Vector erase iterator outside range" when trying to erase a previously saved iterator

在我的项目中,我正在尝试创建一个向量并保存一个迭代器,该迭代器指向我稍后可能想要删除的向量中的某个元素。同时,新元素将添加到向量中,添加一些元素后我想删除我从向量中保存的迭代器。

这是我尝试做的:

std::vector<foo> vec;
vec.push_back(foo());
std::vector<foo>::iterator it = vec.begin();

for (int i = 0; i < 10; i++) {
    vec.push_back(foo());
}

vec.erase(it);

但是这样做会出现执行错误,提示“Vector erase iterator outside range” 为什么这种方法是错误的?我怎样才能做对?

当大小超过保留容量时,向量迭代器在重新分配时失效。由于您没有执行 vec.reserve(10),任何 push_back 都可能使 it.

无效

请注意 .reserve 本身会导致重新分配,因此必须在 it 初始化之前发生。

是的,因为您的代码调用了未定义的行为。

向向量添加项会使所有迭代器失效,使用失效的迭代器会导致未定义的行为。

原因是为向量项保留了一些内存。当此内存不足以容纳新项目时,将分配新的内存片段并将内容复制到新位置。然后释放旧的内存片段。旧的迭代器仍然指向刚刚被释放的旧地方。

在文档中您可以找到:

std::vector<T,Allocator>::push_back - cppreference.com

If the new size() is greater than capacity() then all iterators and references (including the past-the-end iterator) are invalidated. Otherwise only the past-the-end iterator is invalidated.

要解决问题(并使代码更快),您可以 reserve 给定数量的项目 space 所需的数量。

这个例子会告诉你会发生什么,你添加到向量中的元素越多,它需要的内存就越多。向量将“增长”并在内存中移动元素。 (这也是为什么调用 reserve 可以加速你的代码,但那是另一回事了)

#include <vector>
#include <iostream>

struct foo {};

int main()
{

    std::vector<foo> vec;
    vec.push_back(foo());
    std::vector<foo>::iterator it = vec.begin();

    auto capacity = vec.capacity();

    for (int i = 0; i < 20; i++)
    {
        std::cout << "iteration " << i << ", size = " << vec.size() << ", capacity = " << vec.capacity() << "\n";
        vec.push_back(foo());
        if (capacity != vec.capacity())
        {
            std::cout << "vector memory has been reallocated, all iterators are no longer valid\n";
            capacity = vec.capacity();
        }
    }

    //vec.erase(it);
}