C++ primer基础之容器insert
今天学习C++ 基础知识的时候遇到这样问题,始终出现segments fault。最后才发现原来是自己对“容器insert之后迭代器会失效”的理解不够透彻。
题目如下:
假定iv是一个int的vector,下面的程序存在什么错误?你将如何修改?
auto iter = iv.begin(); auto mid = iv.begin() + iv.size() / 2; while(iter != mid){ if(*iter == some_val) iv.insert(iter, 2 * 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 = {1,1,1,1,1,3,4,1}; const int val = 1; auto viBegin = vint.begin(); /*这里需要注意,如果vint.size小于等于1的话,viMid = viBegin 那么就不会进入while循环,所以我们应当单独考虑这种情况*/ auto viMid = vint.begin() + 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(viBegin != viMid){ if(*viBegin == val){ vint.insert(viBegin, 2 * val);35 } ++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 = {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,
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
本文向大家介绍C#基础知识之FileStream,包括了C#基础知识之FileStream的使用技巧和注意事项,需要的朋友参考一下 一、FileStream的基础知识 属性: CanRead 判断当前流是否支持读取,返回bool值,True表示可以读取 CanWrite 判断当前流是否支持写入,返回bool值,True表示可以写入 方法:
概述 环境配置 程序结构 基本语法 数据类型 类型转换 变量 常量和文字 运算符 判断 循环 封装 方法 可空类型 数组 字符串 结构体 枚举 类 继承 多态性 运算符重载 接口 命名空间 预处理指令 正则表达式 异常处理 文件 I/O
数据类型说明 数据类型 16位平台 32位平台 64位平台 char 1 字节 1 字节 1 字节 pointer 2 字节 4 字节 8 字节 short 2 字节 2 字节 2 字节 int 2 字节 4 字节 4 字节 float 4 字节 4 字节 4 字节 double 8 字节 8 字节 8 字节 long 4 字节 4 字节 8 字节 long long 8 字节 8 字节 8 字节
RoadMap 指针与引用 左值引用与右值引用 C++专题-左值与右值 static 与 const https://github.com/huihut/interview#const static 作用 修饰普通变量,修改变量的存储区域和生命周期,使变量存储在静态区,在 main 函数运行前就分配了空间,如果有初始值就用初始值初始化它,如果没有初始值系统用默认值初始化它。 修饰普通函数,表明函数
Swift 是一门全新的用于开发 iOS, OS X 以及 watchOS 应用的编程语言。不过,如果你有 C 或者Objective-C 语言开发经验的话,Swift 的许多地方都会让你感到熟悉。 Swift 为所有 C 和 Objective-C 的类型提供了自己的版本,包括整型值的 Int ,浮点数值的 Double 和 Float ,布尔量值的 Bool ,字符串值的 String 。如同
基础内容说明 组件 说明 最低版本 icon 图标 1.0.0 text 文本 1.0.0 progress 进度条 1.0.0 rich-text 富文本 1.0.0 icon 属性 类型 默认值 必填 说明 最低版本 type string 是 icon的类型,有效值:success, success_no_circle, info, warn, waiting, cancel, downlo