迭代器的失效问题

news2024/11/15 13:43:30

vector的插入与删除

我们首先举例说明vector插入和删除操作返回的是什么迭代器

void print(std::vector<int>& vec)
{
    for(auto it=vec.begin();it!=vec.end();it++)
        std::cout<<*it<<" ";
    std::cout<<std::endl;
}

void test()
{
    /*初始化vector容器*/
    std::vector<int> vec({1,2,3,4,5});
    /*插入前的结果*/
    print(vec);
    /*向vector的第一个位置处插入一个元素*/
    auto it=vec.insert(vec.begin(),6);
    // 插入元素后的返回的迭代器
    std::cout<<*it<<std::endl;
    // 插入后的结果
    print(vec);
    
    //删除vector容器中的第一个元素 
    it=vec.erase(vec.begin());
    // 输出删除元素后返回的迭代器
    std::cout<<*it<<std::endl;
    print(vec);
}

编译运行上述代码

1 2 3 4 5 
6
6 1 2 3 4 5 
1
1 2 3 4 5 

可以看到

  • vector插入元素后返回的迭代器是插入后的元素位置,另外vector插入操作属于前置插入
  • vector删除元素后返回的迭代器是所删除元素的后一个位置 

vector迭代器的失效问题

那么什么是迭代器的失效问题呢?我们继续观察以下代码

void print(std::vector<int>& vec)
{
    for(auto it=vec.begin();it!=vec.end();it++)
        std::cout<<*it<<" ";
    std::cout<<std::endl;
}

void test()
{
    /*初始化vector容器*/
    std::vector<int> vec({1,2,3,4,5,6,7,8});
    /*插入前的结果*/
    print(vec);
    for(auto it=vec.begin();it!=vec.end();it++)
    {
        if(*it%2==0)
            vec.erase(it);
    }
    print(vec);
}

这段代码的实现逻辑是删除掉vector中所有的偶数元素,首先这段代码的逻辑是没问题的,但问题在于这段代码的写法是错误,我们编译运行后会发现

1 2 3 4 5 6 7 8 
Segmentation fault (core dumped)

原因在于,vector在删除元素时,从所删除元素位置开始,一直到最后的元素位置的所有迭代器都是失效了

同理再看这段代码,在所有偶数元素位置前插入一个该偶遇元素减去1的元素

void print(std::vector<int>& vec)
{
    for(auto it=vec.begin();it!=vec.end();it++)
        std::cout<<*it<<" ";
    std::cout<<std::endl;
}

void test()
{
    /*初始化vector容器*/
    std::vector<int> vec({1,2,3,4,5,6,7,8});
    /*插入前的结果*/
    print(vec);
    for(auto it=vec.begin();it!=vec.end();it++)
    {
        if(*it%2==0)
        {
            vec.insert(it,*it-1);
        }
    }

}

编译运行查看

1 2 3 4 5 6 7 8 
Segmentation fault (core dumped)

其原因也在于,在vector扩容前,从插入点开始后的所有元素的迭代器都失效了

另外需要说明的是,假如插入元素后,vector扩容了,那么在此时所以的迭代器就都失效了

vector正确的插入删除操作

删除

void print(std::vector<int>& vec)
{
    for(auto it=vec.begin();it!=vec.end();it++)
        std::cout<<*it<<" ";
    std::cout<<std::endl;
}

void test()
{
    /*初始化vector容器*/
    std::vector<int> vec({1,2,3,4,5,6,7,8});
    /*插入前的结果*/
    print(vec);
    for(auto it=vec.begin();it!=vec.end();){
        if(*it%2==0){
            //删除所有偶数元素,同时更新迭代器
            it=vec.erase(it);
        }else{
            it++;
        }
    }
    print(vec);
}

插入 

void print(std::vector<int>& vec)
{
    for(auto it=vec.begin();it!=vec.end();it++)
        std::cout<<*it<<" ";
    std::cout<<std::endl;
}

void test()
{
    /*初始化vector容器*/
    std::vector<int> vec({1,2,3,4,5,6,7,8});
    /*插入前的结果*/
    print(vec);
    for(auto it=vec.begin();it!=vec.end();it++){
        if(*it%2==0){
            //在偶数元素前插入元素,同时更新迭代器
            it=vec.insert(it,*it-1);
            it++;
        }
    }
    print(vec);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2070844.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Simple RPC - 07 从零开始设计一个服务端(下)_RPC服务的实现

文章目录 PreRPC服务实现服务注册请求处理 设计&#xff1a; 请求分发机制 Pre Simple RPC - 01 框架原理及总体架构初探 Simple RPC - 02 通用高性能序列化和反序列化设计与实现 Simple RPC - 03 借助Netty实现异步网络通信 Simple RPC - 04 从零开始设计一个客户端&#…

【数据结构】堆主要的应用场景

1. 堆排序 所谓堆排序&#xff0c;就是在堆的基础上进行排序。 在讲解堆排序之前&#xff0c;让我们先来回顾一下堆的概念&#xff0c; 1.1 大根堆和小根堆 堆是一种完全二叉树&#xff0c;它有两种形式&#xff0c;一种是大根堆&#xff0c;另外一种是小根堆。 大根堆&…

2023年看过的电影和电视剧

2023年看过的电影 2023年12月21日&#xff1a;三大队 评价&#xff1a;感觉结尾不太突出&#xff0c;但是值得一看。 2023年10月02日&#xff1a;志愿军&#xff1a;雄兵出击 评价&#xff1a;感觉还行&#xff0c;场面还不错。但是记不得太多情节。 2023年08月31日&#xf…

如何将 Parallels Desktop 许可证密钥移至新的 Mac?

根据 Parallels 最终用户许可协议&#xff08;EULA&#xff09;的规定&#xff0c;您最多可以在一台设备上下载、安装和使用 Parallels Desktop 的一个原始副本。但是面对更换新机的用户&#xff0c;可以通过迁移的方式把 Parallels Desktop 许可证密钥移至新的 Mac&#xff0c…

跟《经济学人》学英文:2024年08月24日这期 What to make of America’s topsy-turvy economy

What to make of America’s topsy-turvy economy Don’t panic just yet topsy-turvy&#xff1a;颠倒的&#xff1b;混乱的&#xff1b;乱七八糟的&#xff1b; make of&#xff1a;理解&#xff1b;认为&#xff1b;看待 Make of: 这里的 “make of” 意思是如何理解或解释…

自来水厂供水监控的串口服务器应用

随着城市化进程的加快和人口的不断增长&#xff0c;自来水厂作为城市供水系统的核心组成部分&#xff0c;其稳定性和安全性对于城市的正常运行和居民的生活质量至关重要。传统的供水监控系统存在数据传输效率低、维护成本高、实时性差等问题&#xff0c;难以满足现代城市对供水…

TMDOG的微服务之路_08——使用Docker部署NestJS微服务

TMDOG的微服务之路_08——使用Docker部署NestJS微服务 博客地址&#xff1a;TMDOG的博客 在上一篇博客中&#xff0c;我们探讨了如何使用 NestJS 创建一个简单的微服务架构。为了将这些微服务部署到生产环境&#xff0c;我们可以使用 Docker 来打包和管理这些服务。本篇博客将…

Docker 数据卷的使用

Docker 数据卷的使用 文章目录 Docker 数据卷的使用导引1. 创建数据卷2. 查看创建的数据卷3. 查看数据卷的详细信息 导引 在Docker中&#xff0c;我们在创建并运行容器后&#xff0c;可以通过exec命令进入容器内部进行操作&#xff0c;但会发现一些命令是无法使用的&#xff0…

NSSCTF练习记录:[SWPUCTF 2021 新生赛]pigpig

题目&#xff1a; 根据题目名字和附件名提示&#xff0c;猜测为猪圈密码&#xff0c;对应手动解码 whenthepigwanttoeat

持久层接口开发

通常一个接口定义后&#xff0c;从持久层开始开发。 对于一个新模块需要使用工具生成模型类、mapper接口、mapper映射文件等&#xff0c;下边介绍一个工具用于自动生成代码。 1. 代码生成工具 1.1 安装插件 1.2 重启IDEA&#xff0c;连接mysql 1.3 配置代码生成规则 点击“c…

C++容器之字符串的详解

每日诗词&#xff1a; 我见青山我妩媚&#xff0c;料青山见我应如是。 ——《贺新郎甚矣吾衰矣》【宋】辛弃疾 目录 补漏&#xff1a; vector在分配新内存块后如何进行元素复制 正文&#xff1a; 字符串变量和常量 字符串变量&#xff1a; 解析&#xff1a; 字符串常量…

揭露 Sapiens:未来以人为中心的视觉任务

Sapiens | Meta Meta Reality Labs 隆重推出 Sapiens&#xff0c;这是一个尖端的模型系列&#xff0c;专为四种以人为中心的基本视觉任务而设计&#xff1a;二维姿态估计、身体部位分割、深度估计和表面法线预测。 我们的 Sapiens 模型可无缝处理 1K 高分辨率推理&#xff0c…

加州大学圣地亚哥分校 沉浸式遥操作机器人系统

想象一下&#xff0c;在VR中控制游戏角色时&#xff0c;你的手部动作能够无缝转化为角色的行动。如果将这种体验应用于现实世界中的双手机器人控制&#xff0c;将带来革命性的人机交互体验。随着Apple Vision Pro的问世&#xff0c;这一设想逐渐变为现实。然而&#xff0c;将这…

Velocity模板引擎——若依代码生成器

文章目录 快速入门准备模板数据填充运行代码 基础语法简单类型的变量获取对象类型的变量获取基础语法-循环基础语法—if判断 官网 比较擅长用于邮件&#xff0c;发票&#xff0c;web内容生成、代码生成、网页静态化 模板化的东西适合使用 当然模板引擎不止这一种&#xff0c;还…

记录|C# winform——Chart控件

目录 前言一、重点关注1.1 Chart控件效果1.2 属性1.2.0 位置讲解1.2.1 Titles——标题集合TextToolTip 1.2 .2 Series——图表序列ChartTypeLegends——图例集合 二、数据传入Chart控件2.1 如何传入数据&#xff1f;2.2 如果想限定每次展现的数据量怎么办&#xff1f; 三、标注…

主机安全-网络攻击监测

目录 概述暴力破解&#xff08;SSH爆破为例&#xff09;原理规则攻击模拟告警 端口扫描原理规则攻击模拟告警 流量劫持原理规则攻击模拟告警 参考 概述 本文介绍主机网络层面上的攻击场景&#xff0c;每种攻击场景举一个例子。监测方面以字节跳动的开源HIDS elkeid举例。 针对…

【2】搭建雅特力AT32F437ZMT OpenHarmony轻量系统开发环境

本文用于阐述如何搭建AT32F437ZMT OpenHarmony轻量系统开发环境开源组织地址&#xff1a;https://gitee.com/AT32437_OpenHarmony 1.AT-START-F437雅特力官方开发板相关资料 移植基于at32f437雅特力官方开发板AT-START-F437 AT-START-F437雅特力官方开发板相关资料 2.AT32F43…

采用不高于3次的勒让德多项式拟合原函数

利用勒让德多项式进行拟合的区域是[-1,1]&#xff0c;如果不是这个区域&#xff0c;比如是[a,b]&#xff0c;利用转化到[-1,1]。 参考以下例题计算系数 C语言代码如下 //用三阶的勒让德多项式进行拟合 #include<math.h> #include<stdio.h> #include "main.c…

智能控制,高效节能。ZLG致远电子能源智慧管理解决方案

面对楼宇及建筑群能源管理与设备控制的复杂需求&#xff0c;ZLG致远电子推出了一套能源智慧管理解决方案。该方案集设备管理、任务调度和数据可视化于一体&#xff0c;不仅实现数据的实时监控与分析&#xff0c;还助力系统节能降耗。 ZLG致远电子能源智慧管理解决方案 在ZLG致…

shallowReactive 与 shallowRef

除了之前的 ref与reactive 之外&#xff0c;Vue3 还准备了另外两个API&#xff0c;也是用来对响应式数据做处理&#xff0c;那就是 shallowReactive 与 shallowRef shallowReactive 文档解释&#xff1a;reactive() 的浅层作用形式&#xff0c;只能定义对象类型的数据。和 r…