迭代器失效

迭代器是什么

迭代器类型类似于指针类型,也提供了对对象的间接访问。就迭代器而言,其对象便是容器中的元素或者string对象中的字符。使用迭代器可以访问某个元素,迭代器也能从一个元素移动到另一个元素。迭代器有有效和无效之分,这一点和指针差不多。有效的迭代器指向某个元素,或者指向容器中尾元素的下一位置。

我们可以把迭代器理解为指针 但它又不同于指针 。比如我们用sizeof来测它所占的内存,它并不占四个字节。

vector<int> :: iterator it;
cout<<sizoef(it)<<endl;

在这里插入图片描述可以看到它并不是一个指针的大小。

那我们平时说的迭代器失效是怎么回事呢?

像我们对vector deque 容器进行增加或者是删除元素时,因为vector deque是内存连续的一段空间。当我们进行删除时,删除元素后所有元素都要往前挪一个位置,增加元素时要往后挪一个位置。其后就导致迭代器失效。

#include<iostream>
#include<vector>
using namespace std;

void Test(){
	vector<int>vec;
	for(int i=0;i<10;i++){
	vec.push_back(i);
	}
	vector<int>::iterator it;
	for(it=vec.begin();it!=vec.end();it++){
	if(*it%2==0){
	vec.erase(it);//这里会发生迭代器失效	
		}
	}
	for(it=vec.begin();it!=vec.end();it++){
	cout<<*it<<" ";
	}
}

int main(){
	Test();
	return 0;
}

这个代码就会出现错误
在这里插入图片描述

已经失效的迭代器不能进行++操作,所以程序中断了。不过vector的erase操作可以返回下一个有效的迭代器,所以只要我们每次执行删除操作的时候,将下一个有效迭代器返回就可以顺利执行后续操作了,代码修改如下:

for (it = vec.begin(); it != vec.end(); )
    {
        if (*it%2==0)
        {
            it = vec.erase(it);//更新迭代器it
        }
        it++

这样删除后it指向的元素后,返回的是下一个元素的迭代器,这个迭代器是vector内存调整过后新的有效的迭代器。此时就可以进行正确的删除与访问操作了。上面只是举了删除元素造成的vector迭代器失效问题,对于vector的插入元素也可以同理得到验证,这里就不再进行举例了。

vector迭代器失效问题:
1.当进行erase方法时,指向删除节点的迭代器全部失效,指向
节点之后的迭代器也失效。
2.当进行push_back()方法时,end操作返回的迭代器肯定失效。
3.当插入insert()方法时,插入位置后的迭代器全部失效。

deque迭代器失效问题:
1.对于deque来说 ,插入时除了首尾位置,都会导致迭代器,引用,指针失效。如果在首尾位置插入,迭代器失效,指针引用不会失效。
2.如果在首尾之外的任何位置删除元素,除删除元素外的所有元素迭代器都失效。
3.在受尾删除元素只会使首尾元素的迭代器失效。

另外,对于关联容器(如map, set,multimap,multiset),删除当前的iterator,仅仅会使当前的iterator失效,只要在erase时,递增当前iterator即可。这是因为map之类的容器,使用了红黑树来实现,插入、删除一个结点不会对其他结点造成影响。erase迭代器只是被删元素的迭代器失效,但是返回值为void,所以要采用erase(iter++)的方式删除迭代器。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值