C++迭代器失效问题(insert、erase)
什么是迭代器
迭代器提供了一种方法,使它能够按照顺序访问某个容器所含的各个元素,但无需暴露该容器的内部结构,换句话说迭代器就是指针的简单包装,通过一个模板类封装的对象
迭代器的失效问题
一、迭代器在vector、deque等内存连续的容器删除中失效
对于序列式容器,比如vector,删除当前的iterator会使后面所有元素的iterator都失效。这是因为顺序容器内存是连续分配(分配一个数组作为内存),删除一个元素导致后面所有的元素会向前移动一个位置。(删除了一个元素,该元素后面的所有元素都要挪位置,所以,iter++,已经指向的是未知内存)。
二、迭代器在map\set\mutilset等关联类的容器中删除不失效
在关联类容器(map\set\mutilset)删除当前的iterator,仅仅会使当前的iterator失效,只要在erase时,递增当前iterator即可。这是因为map之类的容器,使用了红黑树来实现,插入、删除一个结点不会对其他结点造成影响。erase迭代器只是被删元素的迭代器失效,但是返回值为void,所以要采用erase(iter++)的方式删除迭代器。
三、迭代器在内存连续的容器中插入元素,插入位置之前的迭代器有效,之后的迭代器失效;内存非连续得容器插入迭代器不失效
insert插入没有返回值,因此insert不能在循环中 连续的 进行插入操作(插入位置之后的迭代器失效,无法遍历)
注意: 正常使用erase删除迭代器是有返回值的,返回的是下一个有效的迭代器,
#include<iostream> #include<thread> #include<string> #include<vector> #include<list> #include<mutex> #include<future> using namespace std; int main() { std::vector<int>v{ 0, 1, 2, 3 }; for (auto i = v.begin(); i != v.end(); i++) { //cout << *i << endl; i=v.erase(i);//迭代器i被删除之后是一个无效的迭代器(nullptr指针),因此不能对i进行任何操作; //erase()返回值指向下一个迭代器 cout << *i << endl; } system("pause"); return 0; }
vector::const_iterator 和 const vector::iterator的区别
前者不能修改容器中的元素,如:*newiter=11 属于错误,可以修改迭代器自身,如:newiter++正确;后者可以修改指向容器的元素,如:*newiter=11正确,迭代器本身不能被修改,如:newiter++错误;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2019-08-13 2017 北京网络赛 E Cats and Fish
2019-08-13 CF 1198 A. MP3 模拟+滑动窗口
2019-08-13 博弈论