• C++ primer 学习笔记之容器insert


    今天在做练习9.22时,始终出现segments fault。最后才发现原来是自己对“容器insert之后迭代器会失效”的理解不够透彻。

    题目如下:

    假定iv是一个int的vector,下面的程序存在什么错误?你将如何修改?

    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 }

    我起初编写的代码如下:

     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.

    从逻辑上来讲,应该是没问题啊,那为什么又会出错呢?原来我忘记了对容器进行插入操作的重要影响“除了end之外,所有的迭代器都会失效!!!”。当完成第一次插入之后,此时的viBegin和viMid已经失效了,那么之后对其的所有操作都是非法的。所以我们必须在每一次插入操作之后对两个迭代器重新赋值。鉴于对viMid的赋值比较麻烦,所以采用另外的方式记录当前迭代器是否到达容器的中点,代码如下:

    /*************************************************************************
        > 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; }

    运行效果如下:

    wanchouchou@wanchouchou-virtual-machine:~/c++/9.*$ ./9.22
    2, 1, 2, 1, 2, 1, 2, 1, 3, 4, 1, 
  • 相关阅读:
    js Object.freeze()
    js Object.seal()
    js数字千分位,三种写法,,拿走。。。
    nodejs mongoose连接mongodb报错,command find requires authentication
    nodejs express 服务代理
    容器监控之cadvisor
    kubernetes 集群卸载清理
    解决目录太大-建立软链接
    与运算(&)、或运算(|)、异或运算(^)
    jpa中将查询的字段返回为Map键值对类型
  • 原文地址:https://www.cnblogs.com/wanyuanchun/p/4069819.html
Copyright © 2020-2023  润新知