c++迭代器失效问题
参考两篇文章: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++迭代器失效问题的更多相关文章
- C++ STL 迭代器失效问题
之前看<C++ Primier>的时候,也解到在顺序型窗口里insert/erase会涉及到迭代器失效的问题,并没有深究.今天写程序的时候遇到了这个问题. 1 莫名其妙的Erase 最初我 ...
- STL的erase()陷阱-迭代器失效总结
下面材料整理自Internet&著作. STL中的容器按存储方式分为两类,一类是按以数组形式存储的容器(如:vector .deque):另一类是以不连续的节点形式存储的容器(如:list.s ...
- C++ Primer : 第九章 : 顺序容器的操作以及迭代器失效问题
顺序容器的添加.访问.删除操作以及forward_list的特殊操作,还有迭代器失效问题. 一.向容器添加元素 // array不支持这些操作 // forward_list有自己撰于的版本的inse ...
- C++ STL中迭代器失效的问题
my_container.erase(iter); 其中my_container是STL的某种容器,iter是指向这个容器中某个元素的迭代器.如果不是在for,while循环中,这种方式删除元素没有问 ...
- 容器大小的改变以及容器操作可能使迭代器失效、vector对象的容量变化
1 改变容器的大小 我们可以使用resize来增加或缩小容器,与往常一样,array不支持resize.如果当前大小大于所要求的大小,容器后面的元素会被删除:如果当前大小小于新大小,会将新元素添加到容 ...
- vector迭代器失效的一种情形
使用过STL的人都应该知道关于迭代器失效的原理,这里以后vector迭代器失效为例: 第一种:当插入一个元素到vector中,如果插入后容器已满,那么容器将新开辟一块内存区域,然后 将原内存中的数据拷 ...
- STL源代码分析--迭代摘要、迭代器失效汇总
Vector 1.内部数据结构:连续存储,比如数组. 2.随机訪问每一个元素,所须要的时间为常量. 3.在末尾添加或删除元素所需时间与元素数目无关,在中间或开头添加或删除元素所需时间随元素数目呈线性变 ...
- Iterator invalidation(迭代器失效)
一.vector 所有读操作.swap.std::swap:都不会引起迭代器失效... clear.operator=.assign:都会引起全部变量迭代器失效 reserve.shrink_to_f ...
- 为什么对string调用swap会导致迭代器失效
一般来说,swap操作将容器内容交换不会导致容器的指针.引用.迭代器失效. 但当容器类型为array和string时除外. 原因在于:SSO (Short String Optimization 指 ...
- 谈谈知识的融会贯通:以“java中的迭代器失效问题”为例
提示 文中涉及知识点: Collection . Iterator Guava 中的 Lists.partition 方法 如果你对这两个知识点不了解,强烈建议阅读文中引用的参考文章. 场景一:以Ar ...
随机推荐
- IO流遍历文件夹下所有文件问题
import java.io.File; /** * @author 王恒 * @datetime 2017年4月20日 下午2:24:32 * @description 递归调用 * */ publ ...
- 解决QQ未启用状态,QQ留言图标未启用
最近由于腾讯升级QQ一些东西,导致QQ图标成未启用状态:如图 解决方法,到腾讯此站点登陆一下即可, http://wp.qq.com/set.html 另外设置 没有保存按钮,如果选择完全公开,到自己 ...
- RabbitMQ 官方NET教程(四)【路由选择】
在上一个教程中,我们构建了一个简单的日志记录系统. 我们能够广播日志消息给所有你的接收者. 在本教程中,我们将为其添加一个功能 - 我们将让日志接收者可以仅订阅一部分消息. 例如,我们将能够仅将关键的 ...
- WPF TextBox 仅允许输入数字
因为在 IValueConverter 实现中,当文本不能转换为目标类型时返回 DependencyProperty.UnsetValue ,Validation.GetHasError 返回 tru ...
- 【java并发】(1)深入理解volatile关键字
volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以 ...
- jQuery 滑动及点击切换效果
效果图如下: 初始化 hover效果:滑动menuitem,‘首页’不变,字体颜色改变,有下划线展示. 即在动态添加boder-bottom,改变字体颜色颜色 .menuItem:hover{ bor ...
- ListView中动态显示隐藏HeaderView和FooterView
ListView中动态显示和隐藏Header&Footer 解决思路: 直接设置HeaderView和FooterView.setVisibility(View.GONE)无效, 布局仍然存在 ...
- Android 4.0 Launcher2源码分析——主布局文件(转)
本文来自http://blog.csdn.net/chenshaoyang0011 Android系统的一大特色是它拥有的桌面通知系统,不同于IOS的桌面管理,Android有一个桌面系统用于管理和展 ...
- 多开 MFC线程
序言:我才编程几年啊!就要处理多线程.对于只写函数的我,这难度简直了!不过MFC的多线程,貌似比较简单,还能处理的了. (1).开MFC多个线程 在视频采集的过程中,如果不使用媒体计数器,会造成主线程 ...
- IE与标准浏览器对事件处理的区别
1.监听 标准 element.addEventListener('click',observer, useCapture); element.removeEventListener('click', ...