【C++】vector迭代器失效


在这里插入图片描述

什么是迭代器失效

  首先,vector迭代器本质上就是原生态指针T*,而迭代器失效就是迭代器底层对应的指针所指向的空间被销毁了,继续使用被销毁的空间,就会导致程序崩溃。
  如果迭代器失效了就不能在使用这个迭代器了,如果使用了,结果是未定义的
在这里插入图片描述

1.因改变底层空间所导致的野指针

会引起其底层空间改变的操作,都有可能是迭代器失效,比如:resize、reserve、insert、assign、push_back等。

以我模拟实现的vector中的insert函数为例:
我们知道reserve扩容空间是深拷贝,深拷贝的过程是这样的:申请新空间,把旧空间给新空间,再把旧空间给释放掉。
这时候问题就来了,在insert中,我要指定pos位置插入数据,但是如果发生了扩容,而我的pos所指向的空间,指向的正是旧空间,pos就跟着被释放,变成野指针。

打个比方:家里搬家了没告诉你,你放学了还傻乎乎的回原来的家,连家门都进不去
在这里插入图片描述

解决方法与建议

解决方法:先记住原来pos的位置,在新空间加上去。
在这里插入图片描述
建议insert插入后,就不要再使用这个迭代器it了,使用了会出一堆坑,it就失效了不能访问,不是一定就失效,但是你不确定什么时候会扩容。
在这里插入图片描述

2.指定位置元素的删除操作–erase

在这里插入图片描述
pos是会失效的,看如下示例:
我们想让迭代器it去遍历整个vector,如果值是偶数的,就删掉
在这里插入图片描述
用第一组数据去跑如图右边的代码,显示是正常的,但是其实是机缘巧合
因为我们erase的逻辑是用后一位的数据去覆盖前一位,看测试样例 1 2 3 4 5,当我们遍历到2时,是不是把它erase掉了?3就到了原来2的位置,4就到了原来3的位置,所以++it时,就直接到了4,不会对3进行判断
第二组数据 1 2 3 4 5 6 为什么会崩溃呢?
6是2的倍数,同时也是这组数据的最后一个数,当它被erase了,6的后一位是_finish,_finish覆盖了6,然后++it,本来it是在[_start,_finish)这个区间里面的,这下直接跑到了_finish的下一位,越界了,直接崩溃
第三组数据 2 2 3 4 5 同理第一组数据,第三组数据不是机缘巧合罢了。连续的偶数,++it就不会对本来要判断的位置进行判断。

解决方法

在使用前,对迭代器重新赋值即可
库里面也是这样写的,erase后会返回被删除元素的下一个位置
在这里插入图片描述

在这里插入图片描述

总结与思考

vector迭代器失效大概率是这两种情况造成的:
1.insert导致我们我们改变了底层空间,导致迭代器变成了野指针
2.erase删除了空间导致迭代器跑到了外面越界了变成了野指针

思考:insert插入以后的迭代器不建议再使用了会出很多坑,而erase能继续用,为什么呢?

其实这两种函数库里面都有提供解决方法,erase之后对迭代器重新赋值了我们可以继续使用,insert也有,insert之后迭代器指向第一个新插入元素。但是我们一般用不着
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值