前言
迭代器相当于是容器上的指针,容器可以自己管理内存,因此迭代器可能失效。如果你在不知情的情况下使用了失效的迭代器,后果是不可预料的。可能程序立即崩掉。
提示:以下是本篇文章正文内容,下面案例可供参考
一、map使用迭代器删除
1.代码如下(示例):map<int,string> m;
m[1]="aaa";
m[2]="bbb";
m[3]="ccc";
m[4]="ddd";
auto iter = m.begin();
while( iter != m.end() )
{
if(iter->first > 2 )
{
m.erase(iter++); //避免迭代器iter失效
}
else
{
++iter;
}
}
2.写法分析:m.erase(iter++);语句,在执行erase之前,iter 已经被加1了。erase会使得以前那个未被加一的 iter 失效,而加了一之后的新的 iter 是有效的。
二、vector使用迭代器删除
代码如下(示例):
vector<int> a = {12, 23, 34, 45, 56, 67, 78, 89};
auto iter = a.begin();
while (iter != a.end())
{
if (*iter > 30)
{
iter = a.erase(iter); //避免iter成为野指针
}
else
{
++iter;
}
}
2.原因分析:vector::erase()的实质是将迭代器后面的元素全部复制一遍,往前移动一个位置,因此a.erase(iter)删除后当前位置即为原iter的后一位,所以需要将删除后返回的位置赋给iter,避免iter直接++成为野指针
总结
所有关联容器(如map,set,multimap,multiset)都可采用上面map使用迭代器删除的方法;
所有序列式容器(如vector,deque,list等)都可采用上面vector使用迭代器删除的方法;
测试程序分享:
#include <iostream>
#include <vector>
#include <map>
#include <string>
using namespace std;
void test_vector()
{
vector<int> a = {12, 23, 34, 45, 56, 67, 78, 89};
auto iter = a.begin();
while (iter != a.end())
{
if (*iter > 30)
{
iter = a.erase(iter);
}
else
{
++iter;
}
}
for (const auto &element : a)
{
cout<<element<<endl;
}
}
void test_map()
{
map<int,string> m;
m[1]="aaa";
m[2]="bbb";
m[3]="ccc";
m[4]="ddd";
auto iter = m.begin();
while( iter != m.end() )
{
if(iter->first > 2 )
{
m.erase(iter++);
}
else
{
++iter;
}
}
for (auto iter = m.begin() ;iter != m.end(); iter++)
{
cout<<iter->first<<":"<<iter->second<<endl;
}
}
int main()
{
test_vector();
test_map();
return 0;
}
程序运行结果:
备注:程序可直接编译运行,需采用C++11编译,即编译时在末尾加上-std=c++11