参考两篇文章:https://blog.csdn.net/skyroben/article/details/70877008

https://lichanghao.github.io/2016/08/01/C++%E4%B8%ADiterator%E5%A4%B1%E6%95%88%E7%9A%84%E9%97%AE%E9%A2%98/

迭代器是一种面向对象的广义指针,用于指向容器中或流中的对象。可以看做是一种指向数据的指针。

失效举例:

删除vector容器中的偶数

代码:

#include  <iostream>
#include <vector>
using namespace std;
void Printvector(vector<int> &l)
{
vector<int>::iterator it = l.begin();
while (it != l.end())
{
if (*it % == )
{
//l.erase(it); //(1) 1 输出之后崩溃
//it=l.erase(it); //(2) 1 3 5 输出之后崩溃
}
cout << *it << " ";
++it;
}
cout << endl;
}
void Testvector()
{
vector<int> l;
l.push_back();
l.push_back();
l.push_back();
l.push_back();
l.push_back();
l.push_back();
Printvector(l);
}
int main()
{
Testvector();
return ;
}

(1)程序输出1之后就崩溃的原因:

通过调试观察现象:

作者解释:明显可以看到使用erase删除某一个结点之后,vector迭代器虽然还是指向当前位置,而且也引起了元素前挪,但是由于删除结点的迭代器就已经失效,指向删除点后面的元素的迭代器也全部失效,所以不能对当前迭代器进行任何操作;需要对迭代器重新赋值或者接收erase它的返回值;

个人理解:迭代器类似于一个指针,指向数据为2的节点时数据被删除,而且没有给迭代器重新赋值,那么此时此迭代器的指向不明确,输出该迭代器位置及后边位置的数据会造成程序崩溃。

那么,如果给进行重新赋值

作者解释:使用it接收erase的返回值,假如vector最后一个元素为奇数按照(2)的方式运行程序是不会崩溃的,这里崩溃的原因就好像数组访问越界,因为元素6已经被删除,不属于vector(数组)了,而你还继续对指向它的指针解引用,所以程序崩溃。

个人理解:对it重新赋值后,遍历到6的位置时不会崩溃,但因为删除6节点后没有重新赋值,造成崩溃。

STL中erase实现的源代码:

 iterator erase(iterator position) {
if (position + != end())
copy(position + , finish, position);
--finish;
destroy(finish);
return position;
}

(3)正确的使用方式

void Printvector(vector<int> &l)
{
vector<int>::iterator it = l.begin();
while (it != l.end())
{
if (*it % == )
{
it = l.erase(it);
}
else
{
cout << *it << " ";
++it;
}
}
cout << endl;
}

即只有在it指向明确的时候才进行输出,否则不输出

c++迭代器失效问题的更多相关文章

  1. C++ STL 迭代器失效问题

    之前看<C++ Primier>的时候,也解到在顺序型窗口里insert/erase会涉及到迭代器失效的问题,并没有深究.今天写程序的时候遇到了这个问题. 1 莫名其妙的Erase 最初我 ...

  2. STL的erase()陷阱-迭代器失效总结

    下面材料整理自Internet&著作. STL中的容器按存储方式分为两类,一类是按以数组形式存储的容器(如:vector .deque):另一类是以不连续的节点形式存储的容器(如:list.s ...

  3. C++ Primer : 第九章 : 顺序容器的操作以及迭代器失效问题

    顺序容器的添加.访问.删除操作以及forward_list的特殊操作,还有迭代器失效问题. 一.向容器添加元素 // array不支持这些操作 // forward_list有自己撰于的版本的inse ...

  4. C++ STL中迭代器失效的问题

    my_container.erase(iter); 其中my_container是STL的某种容器,iter是指向这个容器中某个元素的迭代器.如果不是在for,while循环中,这种方式删除元素没有问 ...

  5. 容器大小的改变以及容器操作可能使迭代器失效、vector对象的容量变化

    1 改变容器的大小 我们可以使用resize来增加或缩小容器,与往常一样,array不支持resize.如果当前大小大于所要求的大小,容器后面的元素会被删除:如果当前大小小于新大小,会将新元素添加到容 ...

  6. vector迭代器失效的一种情形

    使用过STL的人都应该知道关于迭代器失效的原理,这里以后vector迭代器失效为例: 第一种:当插入一个元素到vector中,如果插入后容器已满,那么容器将新开辟一块内存区域,然后 将原内存中的数据拷 ...

  7. STL源代码分析--迭代摘要、迭代器失效汇总

    Vector 1.内部数据结构:连续存储,比如数组. 2.随机訪问每一个元素,所须要的时间为常量. 3.在末尾添加或删除元素所需时间与元素数目无关,在中间或开头添加或删除元素所需时间随元素数目呈线性变 ...

  8. Iterator invalidation(迭代器失效)

    一.vector 所有读操作.swap.std::swap:都不会引起迭代器失效... clear.operator=.assign:都会引起全部变量迭代器失效 reserve.shrink_to_f ...

  9. 为什么对string调用swap会导致迭代器失效

    一般来说,swap操作将容器内容交换不会导致容器的指针.引用.迭代器失效. 但当容器类型为array和string时除外. 原因在于:SSO  (Short String Optimization 指 ...

  10. 谈谈知识的融会贯通:以“java中的迭代器失效问题”为例

    提示 文中涉及知识点: Collection . Iterator Guava 中的 Lists.partition 方法 如果你对这两个知识点不了解,强烈建议阅读文中引用的参考文章. 场景一:以Ar ...

随机推荐

  1. spring 九种设计模式

    spring中常用的设计模式达到九种,我们举例说明: 第一种:简单工厂 又叫做静态工厂方法(StaticFactory Method)模式,但不属于23种GOF设计模式之一. 简单工厂模式的实质是由一 ...

  2. C# 怎么把类文件如(XXX.cs)转为dll文件

    打开VS2012或2017 ,新建项目,选择  类库(.NET Framework),创建好一个项目 在建好的项目中添加需要转的类文件 然后将项目重新生成后,在项目的Debug下就可以找到对应的dll ...

  3. 省市区县的sql语句——城市

    /*SQLyog v10.2 MySQL - 5.5.48 : Database - 省市县****************************************************** ...

  4. 解决 C# webbrowser 弹出json下载问题

    把以下内容保存为 .reg ,然后导入注册表,即可解决C# webbrowser 弹出json下载问题,也可通过程序修改. Windows Registry Editor Version 5.00 [ ...

  5. VS2012 +OpenCv2.4.4配置

    使用OpenCV少了数据读取.填充.存储的麻烦. 转载于opencv官网:对于2010和2.43的配置可以直接挪用到新配置环境 http://www.opencv.org.cn/index.php/V ...

  6. Windows下VS2013 C++编译测试faster-rcnn

    [原创帖!转载请注明出处:http://www.cnblogs.com/LaplaceAkuir/p/6445189.html] 本人最近研究faster-rcnn,在ubuntu成功跑通matlab ...

  7. Arduino ULN2009驱动步进电机

    一.实物图 二.例子代码 注:代码来自老外 http://www.4tronix.co.uk/arduino/Stepper-Motors.php 功能:控制电机正反转 // This Arduino ...

  8. 新浪某个tab 页模仿

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  9. SSM项目中表单分页操作(PageHepler使用)

    Maven pom.xml添加依赖 <dependency> <groupId>com.github.pagehelper</groupId> <artifa ...

  10. 【转载】java实现HTTP请求的三种方式

    目前JAVA实现HTTP请求的方法用的最多的有两种:一种是通过HTTPClient这种第三方的开源框架去实现.HTTPClient对HTTP的封装性比较不错,通过它基本上能够满足我们大部分的需求,Ht ...