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

题目如下:

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

 auto iter = iv.begin();
auto mid = iv.begin() + iv.size() / ;
while(iter != mid){
if(*iter == some_val)
iv.insert(iter, * some_val);
}

我起初编写的代码如下:

 /*************************************************************************
> 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 = {,,,,,,,};
const int val = ;
auto viBegin = vint.begin();
    /*这里需要注意,如果vint.size小于等于1的话,viMid = viBegin 那么就不会进入while循环,所以我们应当单独考虑这种情况*/
auto viMid = vint.begin() + vint.size()/;
if(vint.empty()){
cout << "This vector is empty!" << endl;
return ;
}
if(vint.size() == ){
if(*viBegin == val){
vint.insert(viBegin, * val);
}
goto print;
} while(viBegin != viMid){
if(*viBegin == val){
vint.insert(viBegin, * val); }
++viBegin;
} print:
auto viEnd = vint.end();
viBegin = vint.begin();
while(viBegin != viEnd){
cout << *viBegin << ", ";
++viBegin;
} cout << endl; }

运行的时候出现 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 = {,,,,,,};
const int val = ;
auto viBegin = vint.begin();
/*这里需要注意,如果vint.size小于等于1的话,viMid = viBegin 那么就不会进入while循环,所以我们应当单独考虑这种情况*/
auto mid = vint.size() / ;
if(vint.empty()){
cout << "This vector is empty!" << endl;
return ;
}
if(vint.size() == ){
if(*viBegin == val){
vint.insert(viBegin, * val);
}
goto print;
} while(distance(viBegin, vint.end()) > mid){
if(*viBegin == val){
viBegin = vint.insert(viBegin, * 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.22
, , , , , , , , , , ,

C++ primer 学习笔记之容器insert的更多相关文章

  1. C++ Primer学习笔记(三) C++中函数是一种类型!!!

    C++中函数是一种类型!C++中函数是一种类型!C++中函数是一种类型! 函数名就是变量!函数名就是变量!函数名就是变量! (---20160618最新消息,函数名不是变量名...囧) (---201 ...

  2. C++ Primer学习笔记(二)

    题外话:一工作起来就没有大段的时间学习了,如何充分利用碎片时间是个好问题. 接  C++ Primer学习笔记(一)   27.与 vector 类型相比,数组的显著缺陷在于:数组的长度是固定的,无法 ...

  3. Docker学习笔记 - Docker容器内部署redis

    Docker学习笔记(2-4)Docker应用实验-redist server 和client的安装使用 一.获取redis容器(含客户端和服务端) 二.创建服务端容器 1.在终端A中运行redis- ...

  4. Docker学习笔记 - Docker容器之间的连接

    学习目标: 容器之间可以相互连接访问:: --link redis:redisAlias 准备工作 FROM ubuntu:14.04 RUN apt-get install -y ping RUN  ...

  5. C++ Primer 学习笔记_38_STL实践与分析(12)--集成的应用程序容器:文本查询程序

    STL实践与分析 --容器的综合应用:文本查询程序 引言: 本章中最重点的实例.由于不须要用到multiset与multimap的内容.于是将这一小节提到了前面.通过这个实例程序,大师分析问题的智慧, ...

  6. C++ Primer 学习笔记_46_STL实践与分析(20)--容器特有的算法

    STL实践与分析 --容器特有的算法 与其它顺序容器所支持的操作相比,标准库为list容器定义了更精细的操作集合,使它不必仅仅依赖于泛型操作.当中非常大的一个原因就是list容器不是依照内存中的顺序进 ...

  7. C++ Primer 学习笔记_33_STL实践与分析(7) --容器适配器

    STL实践与分析 --容器适配器 引: 除了顺序容器.标准库还提供了三种顺序容器适配器:queue,priority_queue和stack.适配器是标准库中的概念.包含容器适配器,迭代器适配器和函数 ...

  8. C++ Primer 学习笔记_34_STL实践与分析(8) --引言、pair类型、关联容器

    STL实践与分析 --引言.pair类型.关联容器 引言:     关联容器与顺序容器的本质差别在于:关联容器通过键[key]来存储和读取元素,而顺序容器则通过元素在容器中的位置顺序的存取元素. ma ...

  9. C++ Primer 学习笔记_35_STL实践与分析(9)--map种类(在)

    STL实践与分析 --map类型(上) 引: map是键-值对的集合. map类型通常能够理解为关联数组:能够通过使用键作为下标来获取一个值,正如内置数组类型一样:而关联的本质在于元素的值与某个特定的 ...

随机推荐

  1. HTML基本教程,及一些基本常用标签。

    HTML基本结构,及常用标签 <DOCTYPE html> <html> <head> <meta charset="UTF-8" /&g ...

  2. 开放定址法——线性探测(Linear Probing)

    之前我们所采用的那种方法,也被称之为封闭定址法.每个桶单元里存的都是那些与这个桶地址比如K相冲突的词条.也就是说每个词条应该属于哪个桶所对应的列表,都是在事先已经注定的.经过一个确定的哈希函数,这些绿 ...

  3. [BZOJ3172 ][Tjoi2013]单词(AC自动机)

    Description 不稳定的传送门 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次.单词个数<=200,单词总长度< ...

  4. [BZOJ1045] [HAOI2008] 糖果传递 (中位数)

    Description 题目链接 Solution 这题跟数列的中位数有关, 具体证明见刘汝佳的蓝皮书里 Code #include <cstdio> #include <algor ...

  5. ABAP 7.51 構文書き方変換について

    便利になったなぁと感じたコマンドのメモです.NetWeaver7.40 SP2から使えます. SAP NetWeaver AS for ABAP 7.51 Innovation Package – O ...

  6. DJango跨域中间键

    Skip to main content   Search PyPISearch Help Donate Log in Register django-cors-middleware 1.3.1 pi ...

  7. Android字体大小怎么自适应不同分辨率?

    今天有人问我,android系统不同分辨率,不同大小的手机,字体大小怎么去适应呢?其实字体的适应和图片的适应是一个道理的. 一. 原理如下: 假设需要适应320x240,480x320分辨率.在res ...

  8. objc中的类方法和实例方法有什么本质区别和联系

    类方法: 类方法是属于类对象的 类方法只能通过类对象调用 类方法中的self是类对象 类方法可以调用其他的类方法 类方法中不能访问成员变量 类方法中不能直接调用对象方法 类方法是存储在元类对象的方法缓 ...

  9. 实际遭遇GC回收造成的Web服务器CPU跑高

    今天下午有段时间访问园子感觉不如以前那么快的流畅,上Web服务器一看,果然,负载均衡中的1台云服务器CPU跑高. 上图中红色曲线表示的是CPU占用率.正常情况下,CPU占用率一般在40%以下. 这台云 ...

  10. Lua语言中文手册 转载自网络

    Programming in LuaCopyright ® 2005, Translation Team, www.luachina.net Programming in LuaProgramming ...