vector迭代器失效的处理

1、这里先给几个我们经常遇到的问题:(vs2012编译器)

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

int main()
{
vector<int> A;
for (int i = 0;i < 4;i++)
A.push_back(i);

for (vector<int>::iterator it = A.begin();it != A.end();++it)
{
if (*it == 2)
{
A.erase(it);
}
}

for (vector<int>::iterator it = A.begin();it != A.end();++it)
cout<<*it<<endl;
}

这段代码的意思是删除一个指定的数,编译通过,但是,运行出错:


这里再呈现一个问题:

vector<int> A;
for (int i = 0;i < 4;i++)
A.push_back(i);

for (vector<int>::iterator it = A.begin();it != A.end();++it)
{
if (*it == 2)
{
A.insert(it,100);
}
}

for (vector<int>::iterator it = A.begin();it != A.end();++it)
        cout<<*it<<endl;duile

对了,这里还有一个类似的问题:

vector<int> A;
for (int i = 0;i < 4;i++)
A.push_back(i);

for (vector<int>::iterator it = A.begin();it != A.end();++it)
{
if (*it == 2)
{
//A.insert(it,100);
A.push_back(50);
}
}

for (vector<int>::iterator it = A.begin();it != A.end();++it)
cout<<*it<<endl; 


从上面几个问题中可以看到错误的类型一样,那么问题的根源在哪呢?

以vector为例,当我们插入一个元素时它的预分配空间不够时,它会重新申请一段新空间,将原空间上的元素复制到新的空间上去,然后再把新加入的元素放到新空间的尾部,以满足vector元素要求连续存储的目的。而后原空间会被系统撤销或征做他用,于是指向原空间的迭代器就成了类似于“悬垂指针”一样的东西,指向了一片非法区域。如果使用了这样的迭代器会导致严重的运行时错误就变得很自然了。这也是许多书上叙述vector在insert操作后“可能导致所有迭代器实效”的原因。但是想到这里我不禁想到vector的erase操作的叙述是“会导致指向删除元素和删除元素之后的迭代器失效”。但是明显感觉erase带来失效要比insert来得轻得多。似乎“此失效非彼失效”,想想似乎也是这样的:erase操作是在原空间上进行的,假设有一个存有"12345"序列的vector<int>容器原本指向3的迭代器在我删除2之后无非变成指向4了,我只要注意别用到超过end位置的迭代器不就行了吗?

1.当插入(push_back)一个元素后,end操作返回的迭代器肯定失效。
2.当插入(push_back)一个元素后,capacity返回值与没有插入元素之前相比有改变,则需要重新加载整个容器,此时first和end操作返回的迭代器都会失效。
3.当进行删除操作(erase,pop_back)后,指向删除点的迭代器全部失效;指向删除点后面的元素的迭代器也将全部失效。

能理解么?

现在的问题就是怎么避免这类问题了:

iter=vec.insert(iter);   
iter=vec.erase(iter);  

就是运用vector 函数的返回值来更新迭代器,一切就OK啦! 

对第一个问题改动如下:

for (vector<int>::iterator it = A.begin();it != A.end();)
{
if (*it == 2)
{
it = A.erase(it);
}
else//为什么要用else,自己思考啦
{
it++;
}
}


对第二个问题改动如下:

for (vector<int>::iterator it = A.begin();it != A.end();it++)
{
if (*it == 2)
{
it = A.insert(it,100);
it++;//为何要自增呢?这里只是针对这个程序的
}

}



本文的参考网址为:

http://blog.csdn.net/fstar007/article/details/6928954

http://blog.csdn.net/mqstreetball/article/details/6003935

http://blog.chinaunix.net/uid-756549-id-2609028.html

http://www.docin.com/p-159438783.html

http://www.doc88.com/p-331776526715.html

http://my.oschina.net/myspaceNUAA/blog/55053

http://blog.csdn.net/jfkidear/article/details/7287568

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值