迭代器失效的几种情况_迭代器失效的几种情况总结-程序员宅基地

技术标签: C++  

本文根据常用的容器来总结迭代器失效的几种情况。

1. 序列式容器:vector、deque,数组型或队列型数据结构。该数据结构分配在连续的内存中,当删除一个元素后,内存中的数据会发生移动以保证数据的紧凑。所以删除一个元素后,其他数据的地址发生了变化,之前获取的迭代器根据原有信息就访问不到正确的数据。

解决方法:erase返回下一个有效迭代器的值,itVec=vecData.erase(itVec)。

std::vector<int> vecData;
vecData.push_back(1);
vecData.push_back(2);
vecData.push_back(3);
vecData.push_back(4);

std::vector<int>::iteator itVec = vecData.begin();
while (itVec != vecData.end())
{
    if (*itVec % 2 == 0)
    {
        itVec = vecData.erase(itVec);    // 不能使用vecData.erase(itVec++);迭代器会失效
    }
    else
    {
        itVec++;
    }
}

2. 关联容器:map、set、multiset、map、multimap,树形数据结构。以红黑树或者平衡二叉树组织数据,虽然删除了一个元素,整棵树也会调整,以符合红黑树或者二叉树的规范,但是单个节点在内存中的地址没有变化,变化的是各节点之间的指向关系。删除一个结点不会对其他结点造成影响。erase迭代器只是被删元素的迭代器失效。

解决办法:
1). C++98中map的erase返回值为void,只能使用mapData.erase(itMap++); 先把itMap传值到erase里面,然后itMap自增,最后执行erase,所以itMap在失效前已经自增了  
2). C++11中map的erase可以返回下一个有效迭代器,即itMap=vecMap.erase(itMap);  或者mapData.erase(itMap++);

std::map<string, int> mapData;
mapData["a"] = 1;
mapData["b"] = 2;
mapData["c"] = 3;

std::map<string, int>::iterator itMap = mapData.begin();
while (itMap != mapData.end())
{
    if (strcmp(itMap->first.c_str(), "a") == 0)
    {
        mapData.erase(itMap++);    // C++11中也可以用:itMap = mapData.erase(itMap);
    }
    else
    {
        itMap++;
    }

    /* 以下代码会使迭代器失效
    if (strcmp(itMap->first.c_str(), "a") == 0)
    {
        mapData.erase(itMap);
    }
    itMap++;
    */
}

3. 列表容器:list,链表型数据结构。双向链表,使用不连续分配的内存,删除运算使指向删除位置的迭代器失效,不会使其他迭代器失效。

解决办法:
1). erase返回下一个有效迭代器的值,itList = lstData.erase(itList);               
2). lstData.erase(itList++);

std::list<int> lstData;
lstData.push_back(1);
lstData.push_back(2);
lstData.push_back(3);
lstData.push_back(4);

std::list<int>::iteator itList = lstData.begin();
while (itList != lstData.end())
{
    if (*itList % 2 == 0)
    {
        itList = lstData.erase(itList);    // 也可以使用lstData.erase(itList++);
    }
    else
    {
        itList++;
    }
}

注意:迭代器失效会使程序崩溃,或者出现无法预料的结果。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zm1_1zm/article/details/115699599

智能推荐

Linux Ext2/Ext3/Ext4文件系统_linux子系统邮件网站为什么没有ext2-程序员宅基地

文章浏览阅读3.7k次,点赞4次,收藏27次。目录一、Ext2磁盘结构二、Ext2 索引节点和数据块管理三、Ext3文件系统四、Ext4文件系统一、Ext2磁盘结构 Ext2文件系统的磁盘结构如下图: 任何Ext2分区的第一个块都是引导块,引导块保存了分区和内核启动加载器相关的信息,不受文件系统管理。其余磁盘块被Ext2分成块组,每组包含的数据块和索引节点等都存放在相邻的磁道上,所有的块组大..._linux子系统邮件网站为什么没有ext2

用户行为分析(SQL)_该数据集包含了2017年11月25日至2017年12月3日之间,有行为的约一百万随机用户的所-程序员宅基地

文章浏览阅读1.9k次,点赞3次,收藏27次。一、前言之前在博客记录了一篇行为分析(python)的文章,后来觉得自己可以用SQL再走一遍,也算练练手。数据来源于天池的2020-04-13的“UserBehavior.csv”。数据集包含了2017年11月25日至2017年12月3日之间,有行为的约一百万随机用户的所有行为(行为包括点击、购买、加购、喜欢)。数据集的组织形式和MovieLens-20M类似,即数据集的每一行表示一条用户行为,由用户ID、商品ID、商品类目ID、行为类型和时间戳组成,并以逗号分隔。我自己的MySql版本是5.5,Na_该数据集包含了2017年11月25日至2017年12月3日之间,有行为的约一百万随机用户的所

Azkaban3.51.0 双服务模式安装_azkaban3.51.0 安装-程序员宅基地

文章浏览阅读385次。所需安装包:azkaban-web-server-0.1.0-SNAPSHOT.tar.gzazkaban-exec-server-0.1.0-SNAPSHOT.tar.gzcreate-all-sql-0.1.0-SNAPSHOT.sqlexecute-as-user.c以上安装包下载链接:https://pan.baidu.com/s/1gXsQGSuJx1r1SxzboKM1QQ..._azkaban3.51.0 安装

UE4 图表插件使用文档_ue4图表插件-程序员宅基地

文章浏览阅读5.6k次。UE4图表插件使用文档说明插件概述插件获取插件演示插件配置插件使用创建图表控件控件调节属性备注说明插件概述SCUI插件是一套UE4 UMG图表插件,初衷是为了快速制作智慧城市项目,解决复杂数据展示的难点,简化数据可视化展示开发时间与成本,提供常用的界面控件集,并可对接服务器数据。使用UE4.25,可以在UMG属性栏中添加修改数据,也提供蓝图接口动态添加修改数据,仅支持4种图表:柱状图、折线图、饼状图、环状图,之后再做优化和添加更多实用的图表控件!每个图表控件属性栏中都有可调节属性,也支持动态使用_ue4图表插件

java课设心得体会2000字_java课程设计报告心得体会-程序员宅基地

文章浏览阅读4.1k次。java学习心得总结怎么写编程时一项很严谨的工作:一定要细心,一点点的不严谨,可能会导致整个项目出问题,正所谓:差之毫厘,失之千里;2/4编程要良好地逻辑思维和编程技巧:编程首先要有整体架构,再每个模块去实现;编程技巧主要体现在编程的效率和性能;3/4良好地团队合作精神:任何一个项目都不可能由一个人去完成,一个项目组共同开发,并行开发,最终一起整合;4/4编程的规范性:各行各业都有自己的规范,无规..._java框架工程师课程总结报告2000字

ISP-黑电平校正(BLC)_ob校正-程序员宅基地

文章浏览阅读3.5w次,点赞21次,收藏188次。原理Introduction黑电平(Black Level Correction)也就是黑色的最低点,以8bit数据来说,指在经过一定校准的显示装置上,没有一行光亮输出的视频信号电平。定义图像数据为0时对应的信号电平。Cause那么为什么要进行黑电平校正呢?原因如下:CMOS传感器采集的信息经过一系列转换生成原始RAW格式数据。以8bit数据为例,单个pixel的有效值是0~255,但是实际AD芯_ob校正

随便推点

VSCode开发C、C++环境搭建系列(一)——基于Mingw-w64搭建_vscode mingw64-程序员宅基地

文章浏览阅读9.2k次,点赞18次,收藏65次。前言:本次系列文章详细说明基于VS Code来搭建C、C++的开发环境,本次的操作系统是Windows系统,在Windows上面,会有两种不同主流编译器,及Mingw-W64和MSVC,本文介绍第一种,是系列文章的第一篇。概念辨析:Mingw-w64。是 GCC 的 Windows 版本 ;Cygwin。是一个在windows平台上运行的类UNIX模拟环境,在Windows上面提..._vscode mingw64

linux下编写.sh文件,用于执行傻瓜命令_sudo vi test.sh是新文件-程序员宅基地

文章浏览阅读1.5w次,点赞3次,收藏4次。1, vi test.sh #编辑test.sh文件2,chmod a+x test.sh #给test.sh可执行权限3,编写脚本文件!/bin/bashecho ¨================start repo sync===============¨ repo sync -f -j10 while [ $? == 1 ]; do echo ¨================syn_sudo vi test.sh是新文件

句柄——描述符_句柄符号-程序员宅基地

文章浏览阅读1.3k次。 经常遇到“句柄”一词,也知道他就是某个标识符。我的理解就是,像IP地址一样,它用一个统一的标识规则表示可能有某些相同操作或性质的一类事物。就像IP地址可以掩盖该系统的硬件软件一样,不同的资源,如文件、进程等等。 查了一些资料,他们的基本上局限在windows上,或更加具体的实在MFC上。其实,我查找句柄的含义是因为在Linux下也有句柄的概念,觉得应该好好理解一下。handl_句柄符号

win10电脑开机突然变慢的原因及解决方法_win10开机速度突然变慢-程序员宅基地

文章浏览阅读5.2k次。win10电脑使用一段时间后,开机速度就慢慢的变得越来越慢了,严重拖慢开机速度,有什么办法解决?这是因为系统不断安装软件导致启动项增多拖慢了开机速度,但安装的软件都很重要,有什么办法在不卸载软件的情况下加快开机速度?今天小编就为大家带来了一个非常实用的解决方法。操作步骤:1.进入win10系统桌面,鼠标点击开始按钮,进入下一步。2.在开始菜单的搜索框中输入msconfig并回车打开系统配置..._win10开机速度突然变慢

Swift设计模式之抽象工厂模式_swift抽象方法-程序员宅基地

文章浏览阅读1.1k次。转自Swift设计模式原文Design-Patterns-In-Swift// 抽象工厂模式// 百度百科:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类// 设计模式分类:创建型模式import Foundation/** * 抽象工厂 */protocol Decimal { func stringValue() -> String //_swift抽象方法

.obj重定义解决方法_在obj中重定义-程序员宅基地

文章浏览阅读1.7k次。个人经常写 .h 或 .hpp 文件 且把声明和定义写一起,虽然大多情况下不报错,也正常跑,但是 一旦IDE死脑子转不过来 报了重定义 你就别指望 #pragma once 或者 #ifndef 了,根本不行。 (如果你连pragma once或 ifndef都没声明,那你拉倒吧)这次遇到的错误:在 .h 文件里声明实现的通用的函数,两次include 编译时候报重定义。(之前看别人..._在obj中重定义

推荐文章

热门文章

相关标签