在我的專案中,我正在嘗試創建一個向量并保存一個迭代器,該迭代器指向我稍后可能想要洗掉的向量的某個元素。與此同時,新元素將添加到向量中,在添加一些元素后,我想洗掉我從向量中保存的迭代器。
這就是我試圖做的:
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);
但是通過這樣做,會出現一個執行錯誤,上面寫著“向量擦除迭代器超出范圍”為什么這種方法是錯誤的?我怎樣才能做對?
uj5u.com熱心網友回復:
當大小超過保留容量時,向量迭代器在重新分配時失效。由于您沒有執行vec.reserve(10),因此任何 push_back 都可能使 無效it。
請注意,.reserve它本身可能會導致重新分配,因此必須在it.
uj5u.com熱心網友回復:
是的,因為您的代碼呼叫了未定義的行為。
將項添加到向量會使所有迭代器失效,并且使用失效的迭代器會導致未定義的行為。
原因是向量項有一些保留的記憶體。當此記憶體不足以容納新專案時,會分配新的記憶體片段并將內容復制到新位置。然后釋放舊的記憶體片段。舊迭代器仍然指向剛剛釋放的舊位置。
在檔案中,您可以找到:
std::vector<T,Allocator>::push_back - cppreference.com
如果新的size()大于capacity() ,則所有迭代器和參考(包括過去的迭代器)都將失效。否則只有最后的迭代器無效。
要解決問題(并使代碼更快),您可以為給定數量的專案保留所需的空間量。
uj5u.com熱心網友回復:
這個例子會告訴你會發生什么,你添加到一個向量的元素越多,它需要的記憶體就越多。向量將“增長”并在記憶體中移動元素。(這也是為什么呼叫 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);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/317130.html
下一篇:非靜態成員函式的參考
