C++ primer 學習筆記之容器insert

今天在作練習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, 
相關文章
相關標籤/搜索