c++STL使用时的迭代器失效问题

迭代器失效本质上有两种情况:

        一是pos的意义变了(指向的位置不是想要指向位置),二是pos变成了野指针(使用了一块已经被释放了的空间)。

        迭代器失效会导致程序出现莫名其妙的越界访问、编译报错和获取的位置跟预期不符

STL容器迭代器失效分3类讨论

序列式容器迭代器失效

        容器底层内存连续,允许随机访问。常见下面成员函数的使用可能会导致迭代器失效,本质上还是分 内存重新分配导致的全失效和元素被删除移动导致的意义改变了。

1、push_back() 使迭代器失效。

        在容器末尾添加一个元素。如果容器有剩余空间(capacity() > size()),则直接添加新元素到容器尾部。此时,原迭代器中end()会失效,其他的都不会失效。如果容器没有剩余空间(capacity() == size()),会导致容器重新分配内存,然后将数据从原内存复制到新内存,再在尾部添加新元素。此时,由于内存重新分配,原迭代器(所有)都失效

2、pop_back() 使迭代器失效。

​        直接将容器中的最后一个元素删除,原迭代器中最后一个元素的迭代器和end()会失效,其余的都不会失效。

3、insert(iterator, n) 使迭代器失效。

        如果没有内存的重新分配,原迭代器中插入点及插入点之后的迭代器(包括end())都失效。如果有内存的重新分配,原迭代器(所有)都失效。

4、erase(iterator) 使迭代器失效。

        将删除点及之后的元素都向前移动一位,然后删除最后一个元素。因此,原迭代器中删除点之前的迭代器都有效,删除点之后的元素迭代器都失效。

vector容器迭代器失效
失效类型1--迭代器意义变了:

        对于序列容器vectordeque来说,使用erase后,后边的每个元素的迭代器都会失效,后边每个元素都往前移动一位,erase返回下一个有效的迭代器。

明白上面的机制之后,我们就要注意在for循环里面 使用erase方法,必要时候要适当修正 已经改变意义的迭代器。

案例:

#include<iostream>
#include<vector>
 
using namespace std;
 
int main(){
    
    vector<int> q{1,2,3,4,5,6};
    //在这里想把大于2的元素都删除
    for(auto it=q.begin();it!=q.end();it++){
        if(*it>2)
            q.erase(it);//这里就会发生迭代器失效
    }
    //打印结果
    for(auto it=q.begin();it!=q.end();it++){
        cout<<*it<<" ";
    }
    cout<<endl;
    return 0;
}

输出: 1 2 4 6

解决方案:

//在这里想把大于2的元素都删除
    for(auto it=q.begin();it!=q.end();)
    {
        if(*it>2)
        {
            q.erase(it);//这里删除结束,原来的空就会被后续元素补上,it会直接指向原下一个元素,因此不需要再自加了
        }
        else
        {
            it++;
        }
    }

//或:
    for(auto it=q.begin();it!=q.end();it++)
    {
        if(*it>2)
        {
            it=q.erase(it);//这里会返回指向下一个元素的迭代器,因此不需要再自加了
        }
        else
        {
            --it;
        }
    }

输出: 1 2   

失效类型2--直接变成野指针:

        对于序列容器vectordeque来说,使用可能改变容器内存大小的成员函数,容器就可能重新开空间。原来的封装指针的迭代器就失去了意义:  push_back()、reserve()、insert()

        例如,当使用push_back方法后:

  • 原end返回的迭代器肯定失效(意义变了,end()代表的实际并不是容器末尾了)。
  • end() 之前的迭代器则可能失效,也可能不会失效。取决于push_back操作后,容器capacity有没有变化。如果有变化则会失效,原迭代器成野指针不能再用了,都需要重新赋值。​​​​​​;capacity没有变化,原迭代器则没什么影响,正常使用。

案例:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main(void)
{
 	vector<int> v{ 1, 2, 3, 4, 5 };
  	auto pos =find(v.begin(), v.end(), 3);
   	v.reserve(100);
    *pos = 30;

 	return 0;
}

修改:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main(void)
{
 	vector<int> v{ 1, 2, 3, 4, 5 };
  	auto pos =find(v.begin(), v.end(), 3);
  	//扩容导致迭代器成为野指针
   	v.reserve(100);
   	
   	//这时如果还想更改指定位置的值,那么我们需要进行一个迭代器的更新
  	pos =find(v.begin(), v.end(), 3);
    *pos = 30;

 	return 0;
}

迭代器失效的解决方案就是:更新迭代器,或者通过矫正,让迭代器重新找回定位。

list迭代器失效

        对于list来说,底层结构为带头双向循环链表,它使用了不连续分配的内存。

        插入并不会导致迭代器的失效,不会扩容开辟新空间。

        只有在删除的时候才会导致被删除结点的迭代器失效(野指针)了,其它的迭代器并不会收到影响。

关联式容器迭代器失效【map】

    对于关联容器map、multimap、set、multiset,底层是使用红黑树实现的,所以删除某个元素,仅仅会删除元素的迭代器失效。插入、删除一个结点不会对其他结点造成影响。

        关联容器使用了erase后,当前元素的迭代器失效,但是其结构是红黑树,删除当前元素,不会影响下一个元素的迭代器。

参考:

【C++知识】关于迭代器失效的几种情况_c++迭代器失效-CSDN博客

STL迭代器失效的场景总结_stl 迭代器失效-CSDN博客

https://blog.csdn.net/qq_43148810/article/details/127088856 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络:应用层(一)

我最近开了几个专栏&#xff0c;诚信互三&#xff01; > |||《算法专栏》&#xff1a;&#xff1a;刷题教程来自网站《代码随想录》。||| > |||《C专栏》&#xff1a;&#xff1a;记录我学习C的经历&#xff0c;看完你一定会有收获。||| > |||《Linux专栏》&#xff1…

uniapp,点击选中并改变颜色,第二次点击取消选中状态

一、效果图 二、代码实现 字符串的indexOf和数组的indexOf用法一致&#xff01; arr.indexOf(item) 该方法返回某个元素在数组中的位置。若没检索到&#xff0c;则返回 -1。 关键代码&#xff1a;(通过:class绑定) :class"selectList.indexOf(sub.type) ! -1 ? right_ite…

Linux Zabbix企业级监控平台本地部署并实现远程访问

前言 Zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。能监视各种网络参数&#xff0c;保证服务器系统的安全运营&#xff1b;并提供灵活的通知机制以让系统管理员快速定位/解决存在的各种问题。 本地zabbix web管理界面限制在只能局域…

SD-WAN跨国网络加速的原理

许多企业需要在全球范围内高效传输和交流数据&#xff0c;然而&#xff0c;跨国网络连接面临着多种挑战&#xff0c;如网络延迟、拥塞和数据包丢失&#xff0c;这些问题可能会显著降低企业的运作效率和客户体验。为了克服这些问题&#xff0c;越来越多的企业正在采用SD-WAN跨国…

android悬浮窗气泡点击穿透事件

一个小众功能记录&#xff1a;新增气泡&#xff0c;拖动气泡&#xff0c;点击气泡事件传递到下层 文章底部附上demo 效果&#xff1a; 1、新建一个service&#xff0c;都在这里面实现 左侧悬浮窗&#xff1a; private void setFloatWinow() {floatingView LayoutInflater.…

第二证券:结构性行情或将延续 泛科技有望继续走强

展望未来&#xff0c;当时已进入重要的方针窗口期&#xff0c;能否有超预期的新方针推出是改变商场的要害。但复盘2023年的行情来看&#xff0c;过早买卖方针预期的成功率并不高&#xff0c;因而主张该方位以防御性资产为主&#xff0c;高股息资产从本年9月份至今现已调整了2个…

科研论文中PPT图片格式选择与转换:EPS、SVG 和 PDF 的比较

当涉及论文中的图片格式时&#xff0c;导师可能要求使用 EPS 格式的图片。EPS&#xff08;Encapsulated PostScript&#xff09;是一种矢量图格式&#xff0c;它以 PostScript 语言描述图像&#xff0c;能够无损地缩放并保持图像清晰度。与像素图像格式&#xff08;如 PNG 和 J…

Redis(三):常见数据类型:List、Set、Zset

List 列表 列表类型是用来存储多个有序的字符串&#xff0c; 如图&#xff1a; a、b、c、d、e 五个元素从左到右组成 了⼀个有序的列表&#xff0c;列表中的每个字符串称为元素&#xff08;element&#xff09;&#xff0c;⼀个列表最多可以存储个元素。在 Redis 中&#xff…

虹科分享 | CanEasy多场景应用,让汽车总线测试更简单

CanEasy是一个基于Windows的总线工具&#xff0c;用于分析和测试CAN、CAN FD和LIN以及汽车以太网系统。通过高度自动化和简单的配置模拟总线流量&#xff0c;CanEasy可用于分析真实网络、模拟虚拟系统&#xff0c;以及在整个开发过程中进行剩余总线模拟&#xff0c;实现从测试到…

Todesk、向日葵等访问“无显示器”主机黑屏问题解决

我的环境是 ubuntu 22.04 安装 要安装 video dummy&#xff0c;请在终端中运行以下命令&#xff1a; sudo apt install xserver-xorg-video-dummy配置 video dummy 的配置文件请自行搜索 使用任何文本编辑器打开此文件。 我的是 /etc/X11/xorg.conf 默认配置文件包含以下内…

vue chrome debugger 无效

昨天晚上debbger可以正常运行的&#xff0c;但是早上起来突然间所有的debugger都不会被命中&#xff0c;重装了vscode,也清了浏览器缓存&#xff0c;可是这个bitch还是不行&#xff01;整整折腾了一早上&#xff0c;就是无法解决&#xff0c;没办法只能找找资料 &#xff0c;搜…

dockerfile创建镜像 lNMP+wordpress

dockerfile创建镜像 lNMPwordpress nginx dockernginx mysql dockermysql php dockerphp nginx vim nginx.conf vim Dockerfile docker network create --subnet172.17.0.0/16 --opt "com.docker.network.bridge.name""docker1" mynetwork docker buil…

DeepDrive双转子径向磁通电机

DeepDrive公司开发的是一种高效、高性能、低成本的双转子径向磁通电机系统&#xff08;含控制器&#xff09;。该系统具有较高的成本效益和资源效率&#xff0c;并拥有更高的能效&#xff0c;能显著提升电动车续航能力&#xff0c;同时亦能有效控制生产成本&#xff0c;减少自然…

【LuatOS】简单案例网页点灯

材料 硬件&#xff1a;合宙ESP32C3简约版&#xff0c;BH1750光照度模块&#xff0c;0.96寸OLED(4P_IIC)&#xff0c;杜邦线若干 接线&#xff1a; ESP32C3.GND — OLED.GND — BH1750.GND ESP32C3.3.3V — OLED.VCC — BH1750.VCC ESP32C3.GPIO5 — OLED.SCL — BH1750.SCL E…

智能优化算法应用:基于猫群算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于猫群算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于猫群算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.猫群算法4.实验参数设定5.算法结果6.参考文献7.MA…

c++ map

unordered_map #include <iostream> #include <string> #include <unordered_map>int main() {// 创建包含三个字符串的&#xff08;映射到字符串的&#xff09;unordered_mapstd::unordered_map<std::string, std::string> u {{"red", &qu…

el-collapse 默认展开第一个(实测有效)

<el-collapse accordion v-model"activeCollapse"> <el-collapse-item v-for"(item, index) in assetList" :name"index" :key"item.id" > 我这个是通过循环, 只需要v-model 绑定的值和 name 相等,就可以实现展开 然后就…

調整 Windows server DHCP 日誌存儲大小

(1) 開啟 [Windows PowerShell] (2) 查看 DHCP Server 稽核 Log 設定 PS C:\> Get-DhcpServerAuditLog (3) 設定 DHCP Log 檔案大小 PS C:\> Set-DhcpServerAuditLog -MaxMBFileSize 700 註冊表位置&#xff1a;HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\S…

【产品经理】需求池和版本树

在这个人人都是产品经理的时代&#xff0c;每位入行的产品人进阶速度与到达高度各有不同。本文作者结合自身三年产品行业的经历&#xff0c;根据案例拆解产品行业的极简研发过程、需求池、版本树、产品自我优化等相关具体方法论。 一、产品研发的极简过程 1. 产品概述 产品就…

【笔记】硬件工程师入门基础课程

学习视频&#xff08;b站&#xff09;&#xff1a;硬件工程师入门基础元器件课程 基础元器件课程 p1 电阻1. 定义、特性及参数1.1 色环电阻 识别方法&#xff1a;1.2 伏安特性1.3 基本参数 2.电阻的功能2.1 分压2.2 限流2.3 浪涌保护 3. 如何选择电阻 p2 电容1. 电容的定义1.1电…