deque迭代器失效的困惑?

deque 迭代器失效的问题详解 今天在看STL源码的时候,无意写了如下的代码,发现程序崩溃了: deque::iterator iter=d.begin(); d.insert(iter,5); d.insert(iter,6); //崩溃,迭代器失效了 之前一直没有留意这个问题,后来结合源码和查找资料,得到如下的结论: 插入操作: 1、在队前或队后插入元素时(push_back(),pus 阅读详情

在实现LRU算法的时候lru_list 开始用的是deque 但是因为害怕其在插入删除上的迭代器失效情况的诡异情况。遂用list代替之。

在数据量比较大的时候性能不是很好。性能优化分析的时候决定用deque替换回来。于是对deque迭代器失效的情况好好研究了一下:


c++ primer如此写道:

1.在deque容器首部或者尾部插入元素不会使得任何迭代器失效。 
2.在其首部或尾部删除元素则只会使指向被删除元素的迭代器失效。 
3.在deque容器的任何其他位置的插入和删除操作将使指向该容器元素的所有迭代器失效。


stackoverflow上对此的讨论:Confusion on iterators invalidation in deque



I'm bit confused regarding iterator invalidation in deque. (In the context of this question)

Following is the excerpts from -- The C++ Standard Library: A Tutorial and Reference, By Nicolai M. Josuttis

Any insertion or deletion of elements other than at the beginning or end invalidates all pointers, references, and iterators that refer to elements of the deque.

Following is the excerpts from SGI site:

The semantics of iterator invalidation for deque is as follows. Insert (including push_front and push_back) invalidates all iterators that refer to a deque. Erase in the middle of a deque invalidates all iterators that refer to the deque. Erase at the beginning or end of a deque (including pop_front and pop_back) invalidates an iterator only if it points to the erased element.

IMHO, deque is collection of blocks with first block growing in one direction and the last block in opposite direction.

  -   -  -  
  -   -  -
  |   -  -  ^
  |   -  -  |
  V   -  -  |
      -  -  -
      -  -  -

push_back, push_front should not have any impact on deque iterators ( I agree with Josuttis).

What is the correct explanation? what the standard say on this?

完美的答案:

IMHO, deque is collection of blocks with first block growing in one direction and the last block in opposite direction.

Your opinion is your prerogative, but it's wrong. :)

deque is such a container semantically, but in terms of implementation it's designed to be implemented by one or more blocks of memory. C++'s iterator invalidation rules come from implementation, so this is why. Arguably this is a small abstraction leak but, well, whatever.

The SGI STL documentation is not the proper documentation to read, because the SGI STL is not the C++ Standard Library. Unfortunately, Josuttis is one of those people who calls it "the STL", and this has led to your confusion.


Following is the excerpts from -- The C++ Standard Library: A Tutorial and Reference, By Nicolai M. Josuttis

Any insertion or deletion of elements other than at the beginning or end invalidates all pointers, references, and iterators that refer to elements of the deque.

Put simply, this passage from Josuttis is misleading in implying that the insertion or deletion of elements thatare at the beginning or end do not invalidate pointers, references or iterators … though it's worth noting that he never comes out and asserts this outright.


Here are the real, proper, official rules for std::deque:

C++03

  • Insertion: all iterators and references are invalidated, unless the inserted member is at an end (front or back) of the deque (in which case all iterators are invalidated, but references to elements are unaffected) [23.2.1.3/1]

  • Erasure: all iterators and references are invalidated, unless the erased members are at an end (front or back) of the deque (in which case only iterators and references to the erased members are invalidated) [23.2.1.3/4]

  • Resizing: as per insert/erase [23.2.1.2/1]

C++11

  • Insertion: all iterators and references are invalidated, unless the inserted member is at an end (front or back) of the deque (in which case all iterators are invalidated, but references to elements are unaffected) [23.3.3.4/1]

  • Erasure: erasing the last element invalidates only iterators and references to the erased elements and the past-the-end iterator; erasing the first element invalidates only iterators and references to the erased elements; erasing any other elements invalidates all iterators and references (including the past-the-end iterator) [23.3.3.4/4]

  • Resizing: as per insert/erase [23.3.3.4/1]


Further reading



C++迭代器失效 迭代器失效就是迭代器底层对应指针所指向的空间倍销毁了,导致使用了一块已经被释放了的空间。 容器操作可能使迭代器失效,一个失效的迭代器将不再表示任何元素。使用失效的迭代器是一个严重的程序设计错误,很可能产生与使用未初始化化指针一样的问题。......... 阅读详情

相关推荐

C++ STL——为什么deque.push_back()会使所有容器内的迭代器失效?

目录 引言 STL是如何实现Deque的 Deque.push_back()被执行时发生了什么? 引言 某天研究了下关于迭代器失效的问题,这个链接很清楚地说明了迭代器失效的场合,但是它没有解释原理。 在参考了视频后,我对Deque的架构有了基本理解,其中我最好奇的是:为什么Deque执行push_back指令后所有迭代器会失效? 必须结合Debug工具从源码的角度去分析一波。 工程属性: Windows_SDK:10.0 平台工具集:Visual Studio 2019(v142)

DawdleD的博客 1606

STL中,deque插入或删除元素时,迭代器是否失效的问题

在vs2013上编程测试后,总结如下: deque d1; 在deque中增加任何元素都将使deque的所有迭代器失效。 在deque的中间删除元素将使所有的迭代器失效。 在deque的头或尾(d1.begin(),d1.end())删除元素时,只有指向该元素的迭代器失效。

ZiZhanOld的博客 1364

从OpenClaw到Hermes Agent:AI Agent实战部署与自动化工作流构建

AI Agent(智能体)作为大语言模型(LLM)的能力延伸,其核心原理在于通过工具调用(Tool Calling)与环境交互,使模型从“对话”走向“执行”。这一技术价值在于将自然语言指令转化为具体操作,实现业务流程自动化,从而提升开发与运维效率。在应用场景上,AI Agent广泛适用于自动化运维、智能客服、数据报告生成等重复性任务处理。本文聚焦于两大热门开源框架OpenClaw与Hermes Agent,深入探讨其部署配置、技能扩展及实战联调。通过结合OpenClaw的模块化扩展能力与Hermes Age

weixin_34122810的博客 506

C++ STL容器迭代器失效

vector 1、插入(push_back)元素。end操作返回的迭代器失效 2、插入(push_back)元素,若发生扩容,即capacity返回值有变化,则需重新加载整个容器,此时begin和end操作返回的迭代器都会失效。 3、删除(erase、pop_back)元素,指向删除点的迭代器失效,后面的元素的迭代器也将失效。 qeque 1、在deque容器首部和尾部插入元素不会使任何迭代器失效; 2、在deque容器首部和尾部删除元素,只会使被删除元素的迭代器失效; 3、在deque容器的其他位置

xiaofeilongyu的博客 379

在 Linux 虚拟机中手动安装 VMware Tools

对于 Linux 虚拟机,您可以从命令行手动安装 VMware Tools。对于 Linux 的较高发行版,请使用集成的 open-vm-tools 版本。 前提条件 有关 open-vm-tools 的操作系统兼容性的详细信息,请参见《VMware 兼容性指南》,网址为VMware Compatibility Guide - System Search。 开启虚拟机。 确认客户机操作系统正在运行。 因为 VMware Tools 安装程序是使用 Perl 编写的,请确认已在客户机操作系统中安..

m0_62526815的博客 1757

【NCBI】SRA toolkit安装及使用-Windows&Linux版本

由于市面上的文章介绍SRA toolkit基本上都是基于Linux,而在windows下运行SRA toolkit基本上可以达到相同的效果且更为方便,故本文将分别阐明在Windows和Linux环境下SRA toolkit的安装及使用。

weixin_48076899的博客 2万+

迭代器失效小结

      迭代器(iterator)是一个可以对其执行类似指针的操作(如:解除引用(operator*())和递增(operator++()))的对象,我们可以将它理解成为一个指针。但它又不是我们所谓普通的指针,我们可以称之为广义指针,你可以通过sizeof(vector::iterator)来查看,所占内存并不是4个字节。    首先对于vector而言,添加和删除操作可能使容器的

Make Progress Everyday! 1359

Windows环境下Elasticsearch与JDK版本兼容性实战指南

本文详细解析了Windows环境下Elasticsearch与JDK版本的兼容性问题,提供了从版本匹配检查到安装部署的完整实战指南。重点介绍了Elasticsearch 8.x需JDK 17+等关键版本对应关系,并分享多版本JDK共存方案及性能优化技巧,帮助开发者高效避坑。

weixin_29250403的博客 421

STL容器:deque

1. 概念 vector支持随机访问每个元素,所需要的时间为常量,其在末尾增加或删除元素所需时间与元素数目无关,但是,在中间或开头增加或删除元素所需时间随元素数目呈线性变化。和vector相比,deque 是一个双向开口的连续线性空间,它允许在常数时间内对头端进行元素的插入或删除操作。需要注意的是,虽然deque也支持常数时间的随机访问,但是,由于其数据内存特点,其效率较v

yfk的专栏 6605

从Peer到脉冲地震波:免费Python工具全流程配置教程(PyCharm+Anaconda)

本文详细介绍了如何使用Python工具链(PyCharm+Anaconda)实现从Peer数据库获取地震波数据到生成脉冲地震波的全流程配置。通过开源工具EQTOOL和PySeismicGen,结合Python环境搭建、数据格式转换和脉冲地震动生成技术,为结构抗震分析提供高效、灵活的解决方案。

weixin_29093169的博客 430

从一个 ASIN 看透亚马逊:商品模型背后的增长飞轮

在亚马逊电商体系中,每件商品背后都有一套严密的商品建模逻辑。本篇文章以“ASIN 的一生”为线索,系统拆解了亚马逊的商品模型:从飞轮战略出发,剖析 SDP(Single Detail Page)机制如何实现标准化展示;再到 ASIN 编码、父子变体结构与 Offer 分离模型,逐层解析商品信息如何被建构、聚合与呈现。通过图解与案例,文章帮助读者理解商品建品流程、同款聚合原则、价格控制机制等核心逻辑,避免常见运营误区,是一份面向运营、产品、技术人员的实用参考指南。

曾经“等你生日那天”都遥远得像未来,如今却可欢愉的挥手说“下个十年见” 13万+

deque及迭代器失效问题

deque由一段一段的定量连续空间构成,采用一个表(map)来记录每个连续空间的首址,map是一小块连续的空间,目的是便于迭代器的寻址(map+1即可跳转到下一个连续空间的首址)。map中的每一个元素(node)都是指针,指向另一端(较大的)连续线性空间,称为缓冲区,缓冲区才是deque的储存空间主体。具体机制如下所示: 其中,对迭代器it的解引用得到的是cur位置处对应的元素。 de

ww32cc的博客 5180

把开源 Skills 集成到 LangGraph 项目

1. 定义智能体状态(必须包含 messages,其他字段按需扩展)messages: List[HumanMessage | AIMessage | ToolMessage] # 消息流(核心)skill_output: Optional[str] # 存储 Skill 执行结果next_node: str # 控制流程跳转# 2. 定义智能体决策节点(决定是否调用 Skill)"""智能体决策逻辑:根据用户输入判断是否调用开源 Skill"""# 获取最后一条用户消息。

lpfasd123的博客 902

关于迭代器失效的几种情况

之前就做题的时候就经常碰到与迭代器失效有关的问题,但是一直对这个问题也没有深究,处于似懂非懂的状态,今天就对迭代器失效这部分知识做一个总结。 迭代器 迭代器(iterator)是一个可以对其执行类似指针的操作(如:解除引用(operator*())和递增(operator++()))的对象,我们可以将它理解成为一个指针。但它又不是我们所谓普通的指针,我们可以称之为广义指针,你可以通过sizeo...

everthing willl be ok 2万+

ansys 求解过程中出现未知错误。检查“求解信息”对象上的“求解器输出”,查找可能的原因。-静力学分析遇到的,这是什么原因——An unknown error occurred ——未找到解决方法

点击“确定”关闭弹窗后,进入Workbench的‌“求解信息”对象‌,查看‌“求解器输出”‌,搜索“Error”“Fatal”“Warning”等关键词,找到具体的错误描述,比如材料未定义、网格质量问题、内存不足等,这是精准解决问题的关键。进入“工具-选项-mechanical APDL”,取消勾选“分布式”,GPU加速器选择“none”。在“求解进程设置-高级”中调整内存分配参数,或切换为迭代求解器(如PCG求解器),它更省内存。尝试简化模型,比如删除非关键细节、合并重复部件,分步验证模型,定位问题源。

qq_15963745的博客 616

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

C++ stl迭代器 (迭代器失效问题)

C++剖析stl 迭代器是什么?:迭代器 和 指针;迭代器失效;详解`vector`迭代器失效

知识分享与学习笔记总结,欢迎指点 4667

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

C++ stl迭代器 (迭代器失效问题)_c++ 迭代器失效

🥦 迭代器是指向元素范围(如数组或容器)中的某个元素的任何对象,它能够使用一组运算符(至少具有自增(++) 和解引用 (*) 运算符)循环访问该范围的元素。🍊 迭代器最明显的形式是指针:指针可以指向数组中的元素,并且可以使用增量运算符 (++) 循环访问这些元素。但其他类型的迭代器也是可能的。例如,每个容器类型(如list )都有一个特定的迭代器类型,旨在循环访问其元素。

2401_87255253的博客 1338

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

deque 添加删除元素 迭代器失效问题

deque 添加删除元素 迭代器失效问题 deque的储存空间主体在缓冲区buffer中,由一段一段的定量连续空间组成。为了便于迭代器的寻址,除了此储存空间,deque采用一个表(map)来记录每个连续空间的首地址。map是一小块连续的空间,每个元素(node)都是指针,指向buffer中的各首地址。 指向deque中某元素的迭代器iterator实际结构如图所示,first和last分别...

carol_in_love的博客 2233

STL 容器迭代器失效总结(超级详细)

本文只总结常见的序列容器(vector、deque、list)和关联容器(set、multiset、map、multimap)的迭代器失效问题。 原迭代器指的是进行操作之前保存的迭代器,包括begin()、end()以及其他位置的迭代器。 vector: 成员函数push_back():会在容器末尾添加一个元素。如果容器有剩余空间(capacity() > size()),则直接添加新元素到...

xupeng1644的博客 6493

迭代器失效的问题

文章目录vectordequelist关联容器set map unordered_set unordered_map 迭代器失效的问题,与容器的底层的数据结构有关。 vector (底层时一个可动态扩容的数组,数据的增加与删除都会影响到其他的数据的位置,所以当进行数据增删的时候,其他数据的迭代器有可能会失效) 当插入(push_back)一个元素后,end操作返回的迭代器肯定失效。 当插...

qq_43390943的博客 2581

STL各种容器迭代器失效的时机

STL各种容器迭代器失效的时机 一. 种类: 标准STL序列容器:vector、string、deque和list。 标准STL关联容器:set、multiset、map和multimap。 非标准序列容器slist和rope。slist是一个单向链表,rope本质上是一个重型字符串 非标准关联容器hash_set、hash_multiset、hash_m

Smile&搁浅 5546

迭代器失效问题

迭代器失效问题

atom_linux的博客 2167

STL迭代器及迭代器失效问题

迭代器失效: 典型的迭代器失效. 首先对于vector而言,添加和删除操作可能使容器的部分或者全部迭代器失效。那为什么迭代器会失效呢?vector元素在内存中是顺序存储,试想:如果当前容器中已经存在了10个元素,现在又要添加一个元素到容器中,但是内存中紧跟在这10个元素后面没有一个空闲空间,而vector的元素必须顺序存储一边索引访问,所以我们不能在内存中随便找个地方存储这个元素。

聚精会神搞建设 3287
上一篇: mprotect() failed: Cannot allocate memory
下一篇: iostat -x 1 查看磁盘的IO负载
wteo
博客等级 码龄16年 8粉丝 83原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值