C++ vector容器迭代器失效
一、迭代器失效的原因:
1️⃣:所有可能会引起扩容的操作都可能会导致迭代器失效。如:resize、reserve、insert、assign、push_back等 -------------- 野指针引起的迭代器失效
2️⃣:指定位置的插入和删除都会都可能会导致迭代器失效。如: insert 、erase ----------------- 迭代器指向的位置意义发生改变
迭代器失效的两种情况
1、vector容量不够(引起扩容)
会重新分配内存,然后把原有内存的数据拷贝到新内存上去,导致所有现有的迭代器、指针和引用失效,因为元素在内存中的位置已经改变。
std::vector<int> vec = {1, 2, 3};
auto it = vec.begin();
vec.insert(vec.end(), 4); // 可能触发内存重新分配
// it 现在失效,不能再使用
2、vector容量够
(1)插入点之后的迭代器失效:插入操作会导致插入点之后的所有迭代器失效(包括指向插入点的迭代器),因为元素的位置发生了变化。
(2)插入点之前的迭代器不失效:插入点之前的迭代器保持有效,因为这些元素的存储位置没有改变。
std::vector<int> vec = {1, 2, 3, 4};
auto it = vec.begin() + 1; // 指向元素 2
vec.insert(vec.begin() + 2, 10); // 插入到元素 3 之前
// it 仍然有效,因为它指向插入点之前的元素
3、 特殊情况:插入到末尾
当向 vector 末尾插入元素(使用 insert 或 push_back)时:
(1)如果不发生内存重新分配,所有现有的迭代器都会保持有效。
(2)如果内存重新分配发生,那么所有的迭代器都会失效。
二、避免迭代器失效
保存操作后的迭代器即可。
insert
返回的是指向新插入元素的迭代器。
erase
函数删除指定位置的元素后,返回一个指向被删除元素之后的迭代器。也就是说,它指向的是删除位置的下一个元素。
#include<iostream>
#include<vector>
using namespace std;
void test()
{vector<int> v{1,2,3,4,5,6};auto it = v.begin();//删除偶数while (it != v.end()){if (*it % 2 == 0){auto it = v.erase(it);}else{it++;}}
}