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

C++ STL 容器底层实现与迭代器失效规则总结

本文整理自一次系统的STL学习笔记,重点梳理vectorlistdequemapunordered_map的底层数据结构、时间复杂度、内存模型以及迭代器失效的典型场景。


前言

使用STL容器时,如果只记API而不了解底层机制,很容易写出潜伏的bug。本文从内存布局和源码实现角度,对比分析几个常用容器的核心特性,适合作为面试前或日常开发的知识速查。


一、vector—— 动态数组

1. 底层结构

vector内部维护三个指针(GCC实现中的_M_start_M_finish_M_end_of_storage):

  • _M_start:指向连续内存的起始位置。

  • _M_finish:指向最后一个有效元素的下一个位置size = _M_finish - _M_start)。

  • _M_end_of_storage:指向已分配内存的尾部(capacity = _M_end_of_storage - _M_start)。

2. 扩容机制

_M_finish == _M_end_of_storage时,触发扩容:

  • 新容量通常为原容量的2倍(GCC)或1.5倍(VS)。

  • 步骤:分配新内存 → 移动/拷贝构造元素 → 析构旧元素 → 释放旧内存 → 更新指针。

3. 迭代器失效

  • 插入:若导致扩容,所有迭代器失效;否则插入点之后的迭代器失效。

  • 删除:删除点之后的所有迭代器失效。

安全删除写法:

cpp

for (auto it = v.begin(); it != v.end(); ) { if (条件) it = v.erase(it); else ++it; }

二、list—— 双向链表

1. 底层结构

  • 每个节点包含prevnext指针及数据。

  • 采用哨兵节点(不存储数据)作为头尾标记,简化边界处理。

2. 时间复杂度

  • 随机访问:O(n)(不支持[]

  • 任意位置插入/删除:O(1)(仅改指针)

3. 迭代器失效

  • 插入:任何迭代器均不失效

  • 删除仅被删除元素的迭代器失效,其他迭代器保持有效。

删除写法同样推荐使用it = lst.erase(it);(C++11起erase返回下一个迭代器)。


三、deque—— 双端队列

1. 底层结构

  • 由一段段固定大小的缓冲区组成,缓冲区通过中控器(指针数组)管理。

  • 逻辑上连续,物理上分段。

2. 迭代器结构

deque的迭代器包含4个指针:

  • cur:指向当前元素

  • first/last:当前缓冲区的头/尾

  • node:指向中控器中当前缓冲区的管理单元

3. 时间复杂度

  • 随机访问:O(1)(但有间接寻址)

  • 头/尾插入删除:O(1)

  • 中间插入删除:O(n)(需移动元素)

4. 迭代器失效

  • 头部/尾部插入:迭代器失效,但引用通常不失效。

  • 中间插入所有迭代器失效。

  • 头部/尾部删除:仅被删迭代器失效。

  • 中间删除:删除点之后的迭代器失效。


四、mapunordered_map对比

1. 底层数据结构

  • map红黑树(近似平衡二叉搜索树),元素按键有序

  • unordered_map哈希表(桶数组 + 链地址法),元素无序

2. 时间复杂度

操作mapunordered_map
插入/删除/查找O(log n)平均 O(1),最坏 O(n)
空间开销较大(节点存父/子指针及颜色)相对较小(仅存next指针,但预分配桶数组)

3. 迭代器失效

  • map/set:插入/删除操作不会使任何已有迭代器失效(被删除元素自身的迭代器除外)。

  • unordered_map/unordered_set插入触发rehash时,所有迭代器失效;删除仅使被删迭代器失效。

⚠️ 注意:即便map删除不危及其他迭代器,当前被删的迭代器本身已失效,不能再对其操作。

正确遍历删除:

cpp

for (auto it = m.begin(); it != m.end(); ) { if (条件) it = m.erase(it); else ++it; }

五、快速选型参考

需求场景推荐容器
随机访问 + 尾部操作vector
频繁在中间/头部插入删除list
双端操作 + 随机访问deque
需要有序键值对map
只关心快速查找,不需顺序unordered_map

总结

理解容器的底层实现,有助于写出更健壮、高效的代码,也能在调试时快速定位迭代器相关崩溃。希望这份总结能为你提供实用的参考。

http://www.jsqmd.com/news/1125607/

相关文章:

  • 告别Codex“裸奔”:10个必装Skills解锁AI编程助手真实力
  • 基于大数据爬虫+Hadoop用户偏好迁移的电影推荐系统
  • OpenNRE:清华开源的实体关系抽取工具包
  • SRS 4.0 HTTP回调实战:Spring Boot 2.3.7 实现7种事件鉴权与日志记录
  • sklearn 1.4+ PDP/ICE 图实战:3步代码从原理到特征筛选决策
  • 2026年6月好用的CNC加工服务商
  • eclipse ditto 学习笔记
  • AI替代人力是假象?微软派6000人驻场,Ford召回老工程师,人力价值凸显!
  • Fable 5复活引争议!“内心戏”暴露,AI意识大讨论升温!
  • 斯坦福CS231n计算机视觉课程:从理论到Kaggle实战的完整指南
  • 5分钟快速找回QQ空间全部历史说说的终极指南:GetQzonehistory完整教程
  • Windows系统下Aider完整安装、配置与实战使用教程
  • 地平线6 单机+联机版 全DLC车辆包 附存档免肝解锁
  • java封装好的线程池
  • 完美搞定微博,2026 批量下载微博内容/图片/视频,导出word和pdf,微博内容发布时间链接/点赞/评论/转发等数据导出excel
  • 【Qwt 7.0 系列】总体架构解析 —— 从单体到三库模块化的演进
  • Codex接入DeepSeek模型:从原理到工程化部署的完整指南
  • LangChain:139K Star 的 Agent 工程平台
  • WebTTY:用 WebRTC 直接共享终端,不用搭服务器
  • 模型工厂、三层容错装饰器与JWT认证:从基础设施到可用服务
  • AI技能管理新范式:告别手动复制,实现提示词工程化与资产化
  • Agent 任务中断恢复:状态机比聊天记录更可靠
  • 按键盘Num Lock键会有声音,而且没地方关
  • ubuntu 26.04 k8s 1.36 ceph
  • 纯净系统GH0镜像xp win7 win10 win11 自动还原自动安装 集成标准版驱动 纯净安装工具+详细安装教程
  • 【共创季稿事节】画板应用:ArkTS 中的触摸事件处理
  • 手动拍单容易违规?抖店一键下单、密文下单自动拍单售后合规采购发货模式详解
  • 技术娱乐化时代,AI创业者如何用IP构建第二曲线
  • Claude Code 大规模封号,美团免费提供 GLM-5.2
  • 破界悦己:WATERFLY 如何重新定义当代出行生活