新手发文,可以建议,勿喷~
C++中容器的使用可谓非常广泛,可是使用不当也会造成相当头疼的麻烦。我就C++中常用的容器中常犯的一个erase函数的错误,给大家共享:
erase函数在容器中是不可小觑的一个函数,但是用它同样不可小觑:容器中的迭代器是强大的工具,大家都知道erase函数调用之后容器会自动的缩小自己的长度(也就是size函数的返回值),但是缩小之后,我们就有很多隐患:
(1)迭代子会不会因为容器的长度缩小之后越界;
(2)调用erase函数之后迭代子到什么地方去了;
(3)erase函数调用之后的返回值仍然是迭代子,这个迭代子有何用。
下面我一一作答:
case1:越界是会的,使用容器的erase函数必须要考虑这个情况,具体为什么会这样,请看case2;
case2:调用erase函数之后迭代子就指向了下一个容器元素的地址,这就是为什么有可能越界,比如:
你要擦除的元素正好是容器的最后一个元素,调用erase函数之后,那么就华丽丽的越界了,但是这种越界,有的编译器是看不出什么问题的(因为一般迭代器都是配合循环使用),当程序垮掉的那一刻,我们也很难判断到底是哪儿出的问题。
case3:erase函数返回的迭代子正就是下一个指向下一个元素的迭代子,因此经常用erase函数的返回值来重新赋值我们循环中使用的迭代子。
好了,上一个测试程序【已经编译运行完毕,大家可以放心】:
-
#include <iostream>
-
#include <vector>
-
using namespace std;
-
-
//declare constrait variable as the function returned value
-
const int IS_ERR = 0;
-
const int IS_OK = 1;
-
-
//create a test vector
-
template<typename T>
-
int CreateTestVector(vector<T> &vec,const int iLength,const T initValue)
-
{
-
vec.clear(); //clear vector
-
for (int i = 0; i < iLength; ++i)
-
{
-
vec.push_back(initValue+i);
-
}
-
-
//judge the test vector is create successfully or not
-
if (iLength != vec.size() || initValue != vec.at(0))
-
{
-
return IS_ERR;
-
}
-
-
return IS_OK;
-
}
-
-
//display the elements of vector
-
template<typename T>
-
void DisplayElements(const vector<T> vec)
-
{
-
for (int i = 0; i < vec.size(); ++i)
-
{
-
cout << vec.at(i) <<" ";
-
}
-
cout << endl;
-
}
-
-
//test main function
-
int main()
-
{
-
vector<int> iVec;
-
if (IS_OK != CreateTestVector(iVec,10,11))
-
{
-
return -1;
-
}
-
-
//erase test number
-
int testNum = iVec.at(3);
-
-
cout << "before erase:";
-
DisplayElements(iVec);
-
-
vector<int>::iterator itr = iVec.begin();
-
while (itr != iVec.end())
-
{
-
if (testNum == (*itr))
-
{
-
cout << "erase element: " << *itr << endl;
-
itr = iVec.erase(itr); //assign new itr to old itr
-
}
-
else
-
{
-
++itr;
-
}
-
}
-
-
cout << "after erase:";
-
DisplayElements(iVec);
-
-
return 0;
-
}
阅读(1109) | 评论(0) | 转发(0) |