容器迭代器的失效

       有时容器的迭代器会失效,继续使用这样的迭代器或指针,结果是不确定的。

       先看一段代码:

#include<iostream> 
#include<vector>
using namespace std;
int main(){
vector<int>s;//构造一个空容器
vector<int>::iterator iter=s.begin();
cout<<*iter<<endl;
return 0;
}
       这段程序编译能通过,但是运行出错。原因是,这时s还是一个空容器,里面本来一个元素都没有,何来的指向首元素的迭代器,因此*iter是不可访问的,即 这个迭代器无法解析的,当然这个还不算是迭代器失效的范畴。将第5行改成“vector<int>s(n);”,其中n>=1,这样就不会出错了。

       再看另一段代码:

#include<iostream>
#include<vector>
using namespace std;
int main(){
vector<int>s(5);//构造有5个元素的向量容器,这时每个元素都是0
vector<int>::iterator iter=s.begin();
s.push_back(1);
cout<<*iter<<endl;
return 0;
}

       这时运行时会出错。首先得注意一点,"s.push_back(1);"是不会覆盖s的前面5个元素(都是0)的,而是在第5个0后面再插入1。在插入这个元素1时,s的容量不够(刚开始时只有5个元素的容量,想再插入元素就不够用了。当然,程序在进行了一系列的运行后,s的容量可能大于里面存在 的元素个数。因为向量容器在每次扩展空间时,实际分配的空间一般会大于所需空间,另外将已有元素从容器中删除时多出的空闲空间并不会被释放,再插入元素时可能会重新占用这些空间,这时容量是够的), 这时s会自动用new分配一块更大的空间,使用赋值运算符"="将原有的数据分别复制到新的空间中,并将原有的空间释放。iter指向的原来的空间都释放 了,元素都不在那个空间了,所以这个迭代器就失效了,当然运行出错。当这个迭代器失效后,它也就不能再使用了,当然也就不能再进行诸如++iter,-- iter,iter+=n等的操作了。

        把上面的那段程序改一下就能用了:

#include<iostream>
#include<vector>
using namespace std;
int main(){
vector<int>s(5);
s.push_back(1);
vector<int>::iterator iter=s.begin();//有容量扩展时,先等数据搬到新空间后,
cout<<*iter<<endl;            //再让iter指向新空间中的首元素,这样就不会出错了
return 0;
}
         也可以改成:

#include<iostream>
#include<vector>
using namespace std;
int main(){
vector<int>s(5);
s.reserve(10);//可以在容器尾部插入元素之前先扩大s的容量,
              //这时再插入元素就不会去申请另一块空间了
vector<int>::iterator iter=s.begin();//这句不能放到"s.reserve(10);"的前面,
s.push_back(1);//因为"s.reserve(10);"本来就是要重新申请一块更大的空间
cout<<*iter<<endl;
return 0;
}
        另外,erase(iter),insert(iter)等都可能会引起迭代器的失效。而且,不同的容器,情况也不完全一样,详细情况可以具体参考一下相关书籍。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值