今天在作练习9.22时,始终出现segments fault。最后才发现原来是本身对“容器insert以后迭代器会失效”的理解不够透彻。ios
题目以下:c++
假定iv是一个int的vector,下面的程序存在什么错误?你将如何修改?spa
1 auto iter = iv.begin(); 2 auto mid = iv.begin() + iv.size() / 2; 3 while(iter != mid){ 4 if(*iter == some_val) 5 iv.insert(iter, 2 * some_val); 6 }
我起初编写的代码以下:code
1 /************************************************************************* 2 > File Name: 9.22.cpp 3 > Author: wanchouchou 4 > Mail: 200802376@qq.com 5 > Created Time: 2014年11月02日 星期日 16时34分20秒 6 ************************************************************************/ 7 8 #include<iostream> 9 #include<vector> 10 using namespace std; 11 12 int main(){ 13 vector<int> vint = {1,1,1,1,1,3,4,1}; 14 const int val = 1; 15 auto viBegin = vint.begin();
/*这里须要注意,若是vint.size小于等于1的话,viMid = viBegin 那么就不会进入while循环,因此咱们应当单独考虑这种状况*/ 16 auto viMid = vint.begin() + vint.size()/2;
19 if(vint.empty()){ 20 cout << "This vector is empty!" << endl; 21 return 0; 22 } 23 if(vint.size() == 1){ 24 if(*viBegin == val){ 25 vint.insert(viBegin, 2 * val); 26 } 27 goto print; 28 } 29 30 while(viBegin != viMid){ 31 if(*viBegin == val){ 32 vint.insert(viBegin, 2 * val);35 } 36 ++viBegin; 38 } 39 40 print: 41 auto viEnd = vint.end(); 42 viBegin = vint.begin(); 43 while(viBegin != viEnd){ 44 cout << *viBegin << ", "; 45 ++viBegin; 46 } 47 48 cout << endl; 49 50 }
运行的时候出现 segmentation faulted.blog
从逻辑上来说,应该是没问题啊,那为何又会出错呢?原来我忘记了对容器进行插入操做的重要影响“除了end以外,全部的迭代器都会失效!!!”。当完成第一次插入以后,此时的viBegin和viMid已经失效了,那么以后对其的全部操做都是非法的。因此咱们必须在每一次插入操做以后对两个迭代器从新赋值。鉴于对viMid的赋值比较麻烦,因此采用另外的方式记录当前迭代器是否到达容器的中点,代码以下:it
/************************************************************************* > File Name: 9.22.cpp > Author: wanchouchou > Mail: 200802376@qq.com > Created Time: 2014年11月02日 星期日 16时34分20秒 ************************************************************************/ #include<iostream> #include<vector> using namespace std; int main(){ vector<int> vint = {1,1,1,1,3,4,1}; const int val = 1; auto viBegin = vint.begin();
/*这里须要注意,若是vint.size小于等于1的话,viMid = viBegin 那么就不会进入while循环,因此咱们应当单独考虑这种状况*/ auto mid = vint.size() / 2; if(vint.empty()){ cout << "This vector is empty!" << endl; return 0; } if(vint.size() == 1){ if(*viBegin == val){ vint.insert(viBegin, 2 * val); } goto print; } while(distance(viBegin, vint.end()) > mid){ if(*viBegin == val){ viBegin = vint.insert(viBegin, 2 * val); ++viBegin; } ++viBegin; } print: auto viEnd = vint.end(); viBegin = vint.begin(); while(viBegin != viEnd){ cout << *viBegin << ", "; ++viBegin; } cout << endl; }
运行效果以下:io
wanchouchou@wanchouchou-virtual-machine:~/c++/9.*$ ./9.22 2, 1, 2, 1, 2, 1, 2, 1, 3, 4, 1,