簡體   English   中英

嘗試擦除先前保存的迭代器時出現“矢量擦除迭代器超出范圍”

[英]"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);

但是通過這樣做,會出現一個執行錯誤,上面寫着“向量擦除迭代器超出范圍”為什么這種方法是錯誤的? 我怎樣才能做對?

當大小超過保留容量時,向量迭代器在重新分配時失效。 既然你沒有做vec.reserve(10)任何的push_back的可能的無效it

請注意, .reserve本身會導致重新分配,因此必須在it的初始化之前發生。

是的,因為您的代碼調用了未定義的行為。

將項添加到向量會使所有迭代器失效,並且使用失效的迭代器會導致未定義的行為。

原因是向量項有一些保留的內存。 當此內存不足以容納新項目時,會分配新的內存片段並將內容復制到新位置。 然后釋放舊的內存片段。 舊迭代器仍然指向剛剛釋放的舊位置。

在文檔中,您可以找到:

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

如果新的size()大於capacity() ,則所有迭代器和引用(包括過去的迭代器)都將失效。 否則只有最后的迭代器無效。

要解決問題(並使代碼更快),您可以為給定數量的項目保留所需的空間量。

這個例子會告訴你會發生什么,你添加到一個向量的元素越多,它需要的內存就越多。 向量將“增長”並在內存中移動元素。 (這也是為什么調用 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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM