STL遍历时操作迭代器时迭代器失效
前言
先叠一波甲,这是本人自用博客,如有错误或者有纰漏,是本人菜了,欢迎指正,别喷我。。。
有时我们可能需要在遍历STL容器的时候,同时进行删除,或者插入的操作,如果处理不当会导致迭代器失效,从而引发程序报错。
一、连续空间结构
像vector容器
1、插入
insert返回的迭代器指向插入的new元素,所以下一次正确的位置应该是两次iter1++
int main()
{
vector<int> v{1,2,3,4,5,6,7,8,9};
auto iter1 = v.begin();
while (iter1 != v.end()) {
cout << *iter1 << " ";
// 直接删除会报错
if (*iter1 == 3) {
v.insert(iter1, 20);
// true
/*iter1 = v.insert(iter1, 20);
iter1++;*/
}
iter1++;
}
cout << "---------------" << endl;
for (auto i : v)
{
cout << i << " ";
}
cout << endl;
}
2、删除
删除后,迭代器已经指向下一个正确的位置了,所以continue一下
int main()
{
vector<int> v{1,2,3,4,5,6,7,8,9};
auto iter1 = v.begin();
while (iter1 != v.end()) {
cout << *iter1 << " ";
if (*iter1 == 3) {
//v.erase(iter1);
// true
iter1 = v.erase(iter1);
continue;
}
iter1++;
}
cout << "---------------" << endl;
for (auto i : v)
{
cout << i << " ";
}
cout << endl;
}
二、节点式储存结构
1.删除
同vector 删除
代码如下(示例):
#include<iostream>
#include<map>
using namespace std;
std::map<int, int> mapInfo{ {1, 1}, {22, 2}, {33, 3}, {44, 4}, {55, 5}, {66, 6}, {77, 7} };
int main(){
std::cout << "hello world" << endl;
std::map<int, int>::iterator it = mapInfo.begin();
while (it != mapInfo.end())
{
cout << (it)->first << endl;
if (it->first == 33) {
//mapInfo.erase(it);
// true
it = mapInfo.erase(it);
continue;
}
else {
it++;
}
}
cout << "--------------------" << endl;
for (auto item : mapInfo) {
cout << item.first << " " << item.second << endl;
}
}
总结
像储存数据在连续空间里面的结构 insert或者erase后,原有的迭代器就会失效从而报错。
使用节点式存储的结构 只有erase会导致迭代器失效
insert数据,返回的迭代器指向新插入的数据,erase后,返回的迭代器指向被删除数据的下一位
有些情况下,msvc会认为出错,gun工具下则较为宽松。