当前位置: 首页 > news >正文

迭代器失效问题

一、针对 reserveinserterase 三种操作引发的迭代器失效问题。

以erase为例:
因为erase后,内存重新分配,原有内存释放!所以,不能再使用原有的迭代器!

正确做法:

it = container.erase(it);//左侧it是返回的新迭代器

=》用erase的返回值(更新后的迭代器iter):指向新元素的迭代器!

void vector_iterator_invalidation() {
    cout << "=== vector迭代器失效 ===" << endl;
    vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8};
    
    // ❌ 错误示例:直接删除导致迭代器失效
    /*
    for (auto it = vec.begin(); it != vec.end(); ++it) {
        if (*it % 2 == 0) {
            vec.erase(it);  // ❌ it立即失效!后续++it是“未定义行为”

            //注意:一旦删除,后续就不能再使用迭代器“it”!!
        }
    }
    */
    
    // ✅ 正确做法1:利用erase返回值
    cout << "删除前: ";
    for (int val : vec) cout << val << " ";
    cout << endl;
    
    for (auto it = vec.begin(); it != vec.end(); ) {
        if (*it % 2 == 0) {
            it = vec.erase(it);  // ✅ erase返回下一个有效迭代器

           //注意:erase的返回值时“新内存空间”的迭代器,可以放心使用!
        } else {
            ++it;
        }
    }
    
    cout << "删除后: ";
    for (int val : vec) cout << val << " ";
    cout << endl;
}

void vector_multiple_erase() {
    cout << "=== vector批量删除 ===" << endl;
    vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    
    // ✅ 正确做法2:remove-erase惯用法
    vec.erase(
        remove_if(vec.begin(), vec.end(), 
                 [](int x) { return x % 2 == 0; }),
        vec.end()
    );
    
    cout << "remove_if后: ";
    for (int val : vec) cout << val << " ";
    cout << endl;
}

二、失效规则总结表

容器类型删除操作哪些迭代器失效解决方案:使用返回值
vectorerase被删元素及之后的所有迭代器使用it = erase(it)
dequeerase所有迭代器可能失效使用it = erase(it)
listerase只有被删元素的迭代器使用it = erase(it)
forward_listerase_after只有被删元素的迭代器使用返回值
map/seterase只有被删元素的迭代器使用it = erase(it)
unordered_map/seterase所有迭代器可能失效使用it = erase(it)

关键要点总结1

  1. vector/deque:最严格,删除元素后所有后续迭代器都失效

  2. list/forward_list:最宽松,只有被删元素迭代器失效

  3. 关联容器:中等,只有被删元素迭代器失效

  4. 无序容器:类似vector,可能所有迭代器都失效

三、总结2

操作类型

失效原因

解决方案

reserve

内存重分配导致指针变化

预存有效元素数量

insert

扩容后迭代器定位错误

记录相对偏移量

erase

元素移动导致内容改变

使用返回的迭代器

四、解决方法:

开发建议

  1. 避免在可能触发扩容的操作后直接使用原有迭代器
  2. 优先使用标准库 erase 的返回值(新迭代器);
  3. 在性能敏感场景,提前计算容量避免频繁扩容;
  4. 自定义容器时,严格遵循迭代器失效规则;

黄金法则

  • 使用it = container.erase(it)而不是直接container.erase(it++);

  • 对于序列容器,优先考虑remove-erase惯用法;

  • 在循环中删除时,永远不要保存可能失效的迭代器;

掌握这些规则可以避免90%的迭代器失效问题!

http://www.dtcms.com/a/515702.html

相关文章:

  • Ubuntu 16.04交叉编译arm-linux-gnueabihf的QT5.6.2
  • 神经网络详解
  • 网站如何防止黑客攻击宁波新闻
  • 为打印预览对话框 PrintPreviewDialog 添加保存到 PDF 文件按钮源代码详解
  • Nevercenter CameraBag Photo for mac照片滤镜美化软件
  • 设计模式-策略模式:从鞋厂促销活动看算法的灵活切换
  • Java实现Excel转PDF
  • Fenwick 树进行快速统计
  • Cocos creator2.4.4 处理 16KB 问题
  • 旅游网站的设计的前提成都那家网站做的好
  • undefined reference to `cv::String::dea llocate()‘
  • 计划任务原理及实战
  • 做网站设计最好的公司做旅游网站的论文
  • 【Android】Handler/Looper机制相关的类图和流程图
  • ARM《1》_回顾gcc、动态编译和静态编译、MakeFile的使用
  • 网络环路:隐形威胁的破解之道
  • stm32 can错误中断不处理
  • 我们平常说的连网是指什么?
  • 网站优化人员新乡市延津县建设局网站
  • 网站建设分析从哪几个方面东莞市招聘网
  • 设计模式-责任链模式:从鞋厂审批流程看请求处理的艺术
  • 21_AI智能体开发架构搭建之基于Flask蓝图模块化构建可扩展的知识库服务实践
  • 【手机篇】AI深度学习在手机摄像头模组支架外观检测应用方案
  • 手机版矩阵系统源码搭建与定制开发:深度技术解析与落地实践
  • 做网站首页可以用传媒公司吗软件 项目管理系统
  • 舟山建设工程信息网站北京设计公司招聘
  • Elasticsearch还有哪些常用的分词器?
  • 使用CNN构建VAE
  • TESOLLO:使用MANUS Franka机械臂提高机器人灵活性
  • 西宁建设网站软件陕西交通建设有限公司网站