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