参考两篇文章: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. 大白话理解cookie

    HTTP协议是一个无状态的协议,服务器无法区分出两次请求是否发送自同一服务器. 需要通过会话控制来解决这个问题,会话控制主要有两种方式Cookie 和 Session. Cookie就是一个头,Coo ...

  2. oracle 命令记录

    监听程序启动停止查看名利: 1.切换到oracle用户:su - oracle 2.查看监听状态:lsnrctl status 3.停止监听:lsnrctl stop 4.启动监听:lsnrctl s ...

  3. XML、集合、JSP综合练习

    一.利用DOM解析XML文件得到信息:存入泛型集合中在JSP页面循环打印读取的信息 a)         编写XML文件:添加测试节点数据 b)         建立web项目:在JSP页面中使用DO ...

  4. windows server 2012 r2 安装无法找到install.wim 错误代码0x80070026,以及制作U启动盘决解ISO文件超过5G大小限制的解决方案(转)

    戴尔服务器r530 windows server 2012 r2 安装无法找到install.wim 错误代码0x80070026,以及制作U启动盘决解ISO文件超过5G大小限制的解决方案 关于在服务 ...

  5. Android测试写入文本Log

    写入本地SD卡: @SuppressLint("SdCardPath") public void writeFileSdcard(String fileName, String m ...

  6. Apache2.2 启动和停止命令

    1.启动:net start apache2.2 2.停止:net stop apache2.2

  7. BZOJ 1594: [Usaco2008 Jan]猜数游戏 线段树 + 思维 + 二分

    Code: #include<bits/stdc++.h> #define maxn 3000000 using namespace std; void setIO(string s) { ...

  8. 【转载】深入理解Java的接口和抽象类

    深入理解Java的接口和抽象类 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的 ...

  9. eas左树右表基础资料界面引用为左树右表F7的简单方法

    age:   /** * 加载配件F7(左树右表) * @param F7Filed           要加载的F7控件 * @param ctx               界面上下文 * @单据 ...

  10. eas之常用源码整理

    //查看是否有相关权限 boolean hasAllotPermission=         PermissionFactory.getRemoteInstance().hasFunctionPer ...