目录
1.erase时,尾后递增当前迭代器,即erase(iterator);
2.由于erase()可以返回一个指向被删除元素之后元素的迭代器,所以也可以直接把erase§的返回值赋给当前迭代器,即iterator=erase,如图
1.什么是迭代器
1.在C++中,许多初学者学习迭代器时,会觉得它类似于指针,与指针的操作区别不大,迭代器是类模板,只是他表现得像指针,迭代器可以重载指针的一些操作符,->,*,++ --等封装了指针,是一个“可遍历STL( Standard Template Library)容器内全部或部分元素”的对象,本质在底层实现上其实也是指针实现
2.迭代器只能指向容器,而指针可以指向函数
迭代器的使用以及语法规定
C++ 中迭代器(Iterators)是一种用于遍历容器元素的对象。不同类型的容器(例如 vector、list、map 等)都有相应的迭代器。
迭代器通常使用容器类的成函数begin()和end(),其中begin()返回指向容器第一个元素的迭代器,而end()返回指向容器尾部(最后一个元素的下一个位置)的迭代器。
范围for循环
有趣的是,在c++11中新增的范围for循环实际上就是就是对迭代器的傻瓜式替换,不信请看汇编
这里为了方便观察我使用了我自己实现的vector,实际上就是调用了迭代器,对迭代器进行了一个替换
2.迭代器会失效
什么是迭代器失效
迭代器失效其实就是底层迭代器指针指向的空间销毁了,变成了野指针,也就是使用了一块已经释放的空间,常见的一些容器的容量操作有可能就会导致迭代器失效问题
常见的迭代器失效例子
观察:
1.插入
在连续插入10个数据后 vector容器便会进行扩容,上图可见,两个指向begin()的迭代器地址发生了变化
在容器进行扩容的时候,会进行内容的深拷贝,将原来的值拷贝到完全不同的内存空间去
如图,程序崩溃了,这是由于在VS下,系统会进行强制检查
然而在迭代器失效后,代码并不一定会崩溃,但是运行结果肯定不对,因为实际上已经是野指针了
2.删除
这个原理也是相同的,原来迭代器指向要被删除的数,在删除后,迭代器便指向了一块已经被释放的内存,如图
List的插入为什么不会失效
想想,链表这个数据结构的物理空间本身就是不连续的,所以当插入的时候,并不影响,同理,当删除的时候,如果迭代器还指向被释放的空间,迭代器仍会失效
3.如何避免
在进行对容器进行删除或者插入操作时注意之前迭代器的位置变化
删除操作时:
1.erase时,尾后递增当前迭代器,即erase(iterator);
2.由于erase()可以返回一个指向被删除元素之后元素的迭代器,所以也可以直接把erase§的返回值赋给当前迭代器,即iterator=erase,如图
注意 :
对于vector、string这种在内存中连续存储的只能使用方法1,因为删除元素后,后面元素的迭代器也失效了
对于关联容器,也只能使用方法1,因为它们的erase操作返回值为void,而不是iterator
希望这一节能解决你的问题,当然,有疑问也欢迎提出