reserve(n)仅预分配容量不改变size,避免后续插入时的多次搬迁;resize(n)则调整元素数量并可能触发构造/析构,二者语义不同、不可互换。

提前调用 reserve() 是最直接、最有效的避免频繁搬迁的方法。 它不改变 size(),只预分配足够内存,让后续的 push_back() 在容量充足时完全跳过扩容逻辑。
为什么 reserve(n) 能彻底避开搬迁
因为 reserve() 做的只是“租好大房子”,不搬家具也不造人。它只调整 capacity(),不触碰已有元素,也不调用任何元素的构造或析构函数。只要后续插入总数 ≤ n,就一次搬迁都不会发生。
- 调用
reserve(1000)后,连续 1000 次push_back()全部走快速路径(直接写入、_finish自增) - 如果误用
resize(1000),会默认构造 1000 个int()(即 0),不仅多花时间初始化,还可能掩盖你本意是“预留空间”的真实需求 - 多次调用
reserve()可能导致无效重分配:比如先reserve(100),再reserve(50),后者无效果;而reserve(200)则会触发一次新分配
resize() 和 reserve() 混用时的典型陷阱
两者语义完全不同,但名字太像,容易在初始化阶段写错。尤其当你要“先声明、后填值”时:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 想预留空间 → 用
reserve(n),之后用下标赋值:v[i] = x; - 想直接创建 n 个默认元素 → 用
resize(n),此时v.size() == n,可安全遍历或用at() - 若先
resize(10)再reserve(100),不会出错,但reserve()此时只是确保容量 ≥ 100,已存在的 10 个元素不受影响 - 若先
reserve(100)再resize(10),则size()变为 10,capacity()仍 ≥ 100 —— 这是合法且常见的“预留+精简尺寸”组合
什么时候光靠 reserve() 还不够
当你无法预估最终元素数量,或者数据来自流式输入(如网络包、日志行)时,reserve() 的参数就难定。这时需结合其他策略:
立即学习“C++免费学习笔记(深入)”;
- 按批预估:比如每次读取一个 TCP 包,平均含 50 条记录,那就
reserve(50),处理完清空(clear()不释放内存,下次复用) - 用
shrink_to_fit()收尾:批量处理结束后,若确认不再追加,可尝试回收多余容量(注意:不保证成功,是请求而非命令) - 警惕迭代器失效:所有扩容都会使现存迭代器、指针、引用失效。如果你在循环中边遍历边
push_back(),哪怕只扩容一次,it++就可能访问野地址 —— 这类 bug 往往只在数据量变大时暴露
真正关键的不是“会不会扩容”,而是“能不能预测”。一旦预测失败,搬迁成本就会从 O(N) 累积成 O(N²),而这个拐点常常藏在看似无害的嵌套循环里。

















