C++ primer基础之容器insert

所属分类: 软件编程 / C 语言 阅读数: 69
收藏 0 赞 0 分享

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++中四种对象生存期和作用域以及static的用法总结分析

以下是对C++中四种对象生存期和作用域以及static的用法进行了详细的介绍,需要的朋友可以过来参考下
收藏 0 赞 0 分享

C++嵌套类与局部类详细解析

从作用域的角度看,嵌套类被隐藏在外围类之中,该类名只能在外围类中使用。如果在外围类之外的作用域使用该类名时,需要加名字限定
收藏 0 赞 0 分享

C++空类详解

以下是对C++中的空类进行了详细的介绍,需要的朋友可以过来参考下
收藏 0 赞 0 分享

C++之友元:友元函数和友元类详解

友元是一种允许非类成员函数访问类的非公有成员的一种机制。可以把一个函数指定为类的友元,也可以把整个类指定为另一个类的友元
收藏 0 赞 0 分享

C++中返回指向函数的指针示例

int (*ff(int)) (int *,int);表示:ff(int)是一个函数,带有一个int型的形参,该函数返回int (*) (int *,int),它是一个指向函数的指针,所指向的函数返回int型并带有两个分别是Int*和int型的形参
收藏 0 赞 0 分享

C数据结构之单链表详细示例分析

以下是对C语言中的单链表进行了详细的分析介绍,需要的朋友可以过来参考下
收藏 0 赞 0 分享

C数据结构之双链表详细示例分析

以下是对c语言中的双链表进行了详细的分析介绍,需要的朋友可以过来参考下
收藏 0 赞 0 分享

浅析如何在c语言中调用Linux脚本

如何在c语言中调用Linux脚本呢?下面小编就为大家详细的介绍一下吧!需要的朋友可以过来参考下
收藏 0 赞 0 分享

深入解析unsigned int 和 int

以下是对unsigned int和int进行了详细的分析介绍,需要的朋友可以过来参考下
收藏 0 赞 0 分享

浅谈C++中的string 类型占几个字节

本篇文章小编并不是为大家讲解string类型的用法,而是讲解我个人比较好奇的问题,就是string 类型占几个字节
收藏 0 赞 0 分享
查看更多