当前位置: 首页 > news >正文

迭代器的失效问题

vector的插入与删除

我们首先举例说明vector插入和删除操作返回的是什么迭代器

void print(std::vector<int>& vec)
{for(auto it=vec.begin();it!=vec.end();it++)std::cout<<*it<<" ";std::cout<<std::endl;
}void test()
{/*初始化vector容器*/std::vector<int> vec({1,2,3,4,5});/*插入前的结果*/print(vec);/*向vector的第一个位置处插入一个元素*/auto it=vec.insert(vec.begin(),6);// 插入元素后的返回的迭代器std::cout<<*it<<std::endl;// 插入后的结果print(vec);//删除vector容器中的第一个元素 it=vec.erase(vec.begin());// 输出删除元素后返回的迭代器std::cout<<*it<<std::endl;print(vec);
}

编译运行上述代码

1 2 3 4 5 
6
6 1 2 3 4 5 
1
1 2 3 4 5 

可以看到

  • vector插入元素后返回的迭代器是插入后的元素位置,另外vector插入操作属于前置插入
  • vector删除元素后返回的迭代器是所删除元素的后一个位置 

vector迭代器的失效问题

那么什么是迭代器的失效问题呢?我们继续观察以下代码

void print(std::vector<int>& vec)
{for(auto it=vec.begin();it!=vec.end();it++)std::cout<<*it<<" ";std::cout<<std::endl;
}void test()
{/*初始化vector容器*/std::vector<int> vec({1,2,3,4,5,6,7,8});/*插入前的结果*/print(vec);for(auto it=vec.begin();it!=vec.end();it++){if(*it%2==0)vec.erase(it);}print(vec);
}

这段代码的实现逻辑是删除掉vector中所有的偶数元素,首先这段代码的逻辑是没问题的,但问题在于这段代码的写法是错误,我们编译运行后会发现

1 2 3 4 5 6 7 8 
Segmentation fault (core dumped)

原因在于,vector在删除元素时,从所删除元素位置开始,一直到最后的元素位置的所有迭代器都是失效了

同理再看这段代码,在所有偶数元素位置前插入一个该偶遇元素减去1的元素

void print(std::vector<int>& vec)
{for(auto it=vec.begin();it!=vec.end();it++)std::cout<<*it<<" ";std::cout<<std::endl;
}void test()
{/*初始化vector容器*/std::vector<int> vec({1,2,3,4,5,6,7,8});/*插入前的结果*/print(vec);for(auto it=vec.begin();it!=vec.end();it++){if(*it%2==0){vec.insert(it,*it-1);}}}

编译运行查看

1 2 3 4 5 6 7 8 
Segmentation fault (core dumped)

其原因也在于,在vector扩容前,从插入点开始后的所有元素的迭代器都失效了

另外需要说明的是,假如插入元素后,vector扩容了,那么在此时所以的迭代器就都失效了

vector正确的插入删除操作

删除

void print(std::vector<int>& vec)
{for(auto it=vec.begin();it!=vec.end();it++)std::cout<<*it<<" ";std::cout<<std::endl;
}void test()
{/*初始化vector容器*/std::vector<int> vec({1,2,3,4,5,6,7,8});/*插入前的结果*/print(vec);for(auto it=vec.begin();it!=vec.end();){if(*it%2==0){//删除所有偶数元素,同时更新迭代器it=vec.erase(it);}else{it++;}}print(vec);
}

插入 

void print(std::vector<int>& vec)
{for(auto it=vec.begin();it!=vec.end();it++)std::cout<<*it<<" ";std::cout<<std::endl;
}void test()
{/*初始化vector容器*/std::vector<int> vec({1,2,3,4,5,6,7,8});/*插入前的结果*/print(vec);for(auto it=vec.begin();it!=vec.end();it++){if(*it%2==0){//在偶数元素前插入元素,同时更新迭代器it=vec.insert(it,*it-1);it++;}}print(vec);
}


http://www.mrgr.cn/news/12592.html

相关文章:

  • 【RabbitMQ工作原理相关】
  • 如何在算家云搭建模型Linly-Dubbing(语音识别)
  • 谷歌浏览器http自动跳转https问题
  • 利用 Redisson 实现延迟消息队列:一种高效订单取消方案
  • 【2024年】为Python股票量化分析最新整理的免费股票数据API接口之实时数据
  • yocto配置多线程编译
  • ROS 2--package.xml指令
  • 刷机维修进阶教程-----小米系列机型手机端 直接修改参数步骤解析
  • 代码随想录算法训练营第三十九天| 图论理论基础
  • LeetCode:反转区间内的链表
  • 2024年最大规模的“裁员潮”的起因经过
  • 备战秋招60天算法挑战,Day26
  • 类和对象(4)
  • 【uniapp/uview1.x】u-collapse 高度随内容自适应
  • 【开发心得】筑梦上海:项目风云录(1)
  • ARM程序的组成和执行过程
  • Kafka简单搭建及常用命令
  • 【数据结构与算法】深入理解归并排序(Merge Sort)
  • 一个简单的springboot项目(有源码)
  • Threadlocal+拦截器+JWT实现登录