Chinaunix首页 | 论坛 | 博客
  • 博客访问: 417037
  • 博文数量: 168
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 0
  • 用 户 组: 普通用户
  • 注册时间: 2013-09-09 13:46
文章分类

全部博文(168)

文章存档

2015年(51)

2014年(30)

2013年(87)

我的朋友

分类: C/C++

2013-10-12 16:41:01

新手发文,可以建议,勿喷~

C++中容器的使用可谓非常广泛,可是使用不当也会造成相当头疼的麻烦。我就C++中常用的容器中常犯的一个erase函数的错误,给大家共享:

erase函数在容器中是不可小觑的一个函数,但是用它同样不可小觑:容器中的迭代器是强大的工具,大家都知道erase函数调用之后容器会自动的缩小自己的长度(也就是size函数的返回值),但是缩小之后,我们就有很多隐患:
(1)迭代子会不会因为容器的长度缩小之后越界;
(2)调用erase函数之后迭代子到什么地方去了;
(3)erase函数调用之后的返回值仍然是迭代子,这个迭代子有何用。

下面我一一作答:
case1:越界是会的,使用容器的erase函数必须要考虑这个情况,具体为什么会这样,请看case2;
case2:调用erase函数之后迭代子就指向了下一个容器元素的地址,这就是为什么有可能越界,比如:
           你要擦除的元素正好是容器的最后一个元素,调用erase函数之后,那么就华丽丽的越界了,但是这种越界,有的编译器是看不出什么问题的(因为一般迭代器都是配合循环使用),当程序垮掉的那一刻,我们也很难判断到底是哪儿出的问题。
case3:erase函数返回的迭代子正就是下一个指向下一个元素的迭代子,因此经常用erase函数的返回值来重新赋值我们循环中使用的迭代子。

好了,上一个测试程序【已经编译运行完毕,大家可以放心】:

点击(此处)折叠或打开

  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;

  4. //declare constrait variable as the function returned value
  5. const int IS_ERR = 0;
  6. const int IS_OK = 1;

  7. //create a test vector
  8. template<typename T>
  9. int CreateTestVector(vector<T> &vec,const int iLength,const T initValue)
  10. {
  11.     vec.clear(); //clear vector
  12.     for (int i = 0; i < iLength; ++i)
  13.     {
  14.         vec.push_back(initValue+i);
  15.     }

  16.     //judge the test vector is create successfully or not
  17.     if (iLength != vec.size() || initValue != vec.at(0))
  18.     {
  19.         return IS_ERR;
  20.     }

  21.     return IS_OK;
  22. }

  23. //display the elements of vector
  24. template<typename T>
  25. void DisplayElements(const vector<T> vec)
  26. {
  27.     for (int i = 0; i < vec.size(); ++i)
  28.     {
  29.         cout << vec.at(i) <<" ";
  30.     }
  31.     cout << endl;
  32. }

  33. //test main function
  34. int main()
  35. {
  36.     vector<int> iVec;
  37.     if (IS_OK != CreateTestVector(iVec,10,11))
  38.     {
  39.         return -1;
  40.     }

  41.     //erase test number
  42.     int testNum = iVec.at(3);

  43.     cout << "before erase:";
  44.     DisplayElements(iVec);

  45.     vector<int>::iterator itr = iVec.begin();
  46.     while (itr != iVec.end())
  47.     {
  48.         if (testNum == (*itr))
  49.         {
  50.             cout << "erase element: " << *itr << endl;
  51.             itr = iVec.erase(itr); //assign new itr to old itr
  52.         }
  53.         else
  54.         {
  55.             ++itr;
  56.         }
  57.     }

  58.     cout << "after erase:";
  59.     DisplayElements(iVec);

  60.     return 0;
  61. }


           
阅读(1114) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~