C++迭代器与迭代器失效问题以及如何避免

目录

1.什么是迭代器

迭代器的使用以及语法规定

范围for循环

2.迭代器会失效

什么是迭代器失效

常见的迭代器失效例子

​编辑

List的插入为什么不会失效

3.如何避免

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

希望这一节能解决你的问题,当然,有疑问也欢迎提出

  • 13
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值