容器虽然好用,但是使用时很容易出现访问越界的情况。
越界经常出现在两种情况:
1.添加或者删除元素会导致容器的大小变化,确保迭代的首末地址重新加载。
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector<int> ival;
for(int i = 0; i < 10; ++i)
ival.push_back(i);
//****************这个例子很能说明问题***************//
//注意我没有使用下面注释掉的代码,而在循环中不断的或得插入元素后新的ival.end()
//vector<int>::iterator end = ival.end();
vector<int>::iterator begin = ival.begin();
while(begin != ival.end())
if(*begin == 5)
{
begin = ival.insert(begin,500);
begin = begin + 2;
}
else
begin++;
for(vector<int>::iterator begin = ival.begin();begin != ival.end();)
cout<<*begin++<<endl;
return 0;
}
2.添加或者删除元素导致迭代器位置的变化
#include <iostream>
#include <vector>
#include <list>
using namespace std;
int main()
{
int ia[] = {0,1,1,2,3,5,8,13,21,55,89};
vector<int> iVec(ia,ia+11);
list<int> iList(ia,ia+11);
/*
//删除list中奇数元素
for(list<int>::iterator lit = iList.begin();lit != iList.end();++lit)
{
if(*lit % 2 != 0)
{
lit = iList.erase(lit);
--lit;
}
}
*/
//删除list中奇数元素
for(list<int>::iterator lit = iList.begin();lit != iList.end();)
{
if(*lit % 2 != 0)
{
lit = iList.erase(lit);
}
else
++lit;
}
/*
//删除vector中的偶素元素
for(vector<int>::iterator vit = iVec.begin();vit != iVec.end();++vit)
{
if(*vit % 2 == 0)
{
//删除后返回的指针指向被删除元素后面的元素
vit = iVec.erase(vit);
--vit;
}
}
*/
//删除vector中的偶素元素
for(vector<int>::iterator vit = iVec.begin();vit != iVec.end();)
{
if(*vit % 2 == 0)
{
//删除后返回的指针指向被删除元素后面的元素
vit = iVec.erase(vit);
}
else
++vit;
}
cout<<"list number: odd"<<endl;
for(list<int>::iterator lit = iList.begin();lit != iList.end();++lit)
cout<<*lit<<"\t";
cout<<endl;
cout<<"vector number: even"<<endl;
for(vector<int>::iterator vit = iVec.begin();vit != iVec.end();++vit)
cout<<*vit<<"\t";
return 0;
}
使用注释掉的代码会导致程序运行时失败,虽然二者看起来差别不大。这是因为:第一个数字如果满足条件,那么你erase的返回值的确是下一个元素,但是它也是第一个元素,如果你此时迭代器--,那么必然已经越界了。