reserve只预分配capacity不改变size,调用后size不变、capacity可能增大,越界访问仍崩溃;resize才真正改变size并构造/析构元素。

reserve 不改变 size,只预分配 capacity
很多人以为 reserve 是“让 vector 变大”,其实它只动内存、不动逻辑长度。调用后 vec.size() 仍是原来值,vec.capacity() 才可能变大;访问下标越界依然会崩,因为没构造元素。
- 常见错误:调用
vec.reserve(100)后直接写vec[50] = 42→ 未定义行为(UB),不是越界检查失败,是根本没那块可安全写的内存 - 适用场景:你明确知道后续要 push_back 大量元素(比如读文件逐行塞入),提前
reserve避免多次 realloc + memcpy - 性能影响:
reserve本身不构造对象,开销≈malloc;但如果预留过大,浪费内存,还可能触发 OS 内存延迟分配策略,实际写入时才真正占物理页
resize 真正改变 size,会构造/析构元素
resize 是逻辑扩容或缩容:新位置调默认构造函数(内置类型是零初始化),删掉的位置调析构函数。它同时改 size() 和可能改 capacity()(缩容时不一定释放内存)。
- 常见错误:对含非默认构造函数的对象(比如
std::vector<:string></:string>)调resize(n),结果每个元素都执行了默认构造——如果你本意只是预留空间,这就白花了构造开销 - 参数差异:
resize(n)用默认值填充;resize(n, val)用val拷贝构造新元素;缩容(n )会析构尾部多余元素 - 兼容性注意:C++11 起
resize对 move-only 类型(如std::unique_ptr)也安全,但前提是类型支持移动或拷贝
什么时候该用 reserve,什么时候该用 resize?
关键看你要不要“立刻拥有 n 个可用元素”:
- 只要后续频繁
push_back,且能预估总数 → 用reserve(快、轻量、无构造) - 需要随机访问下标、或要求容器里真有 n 个活对象(比如初始化配置数组、填空矩阵)→ 用
resize - 混合场景(先 reserve 再 resize):不推荐。resize 可能重新分配内存,抵消 reserve 效果;若真要这样,直接 resize 更清晰
- 性能陷阱:对小对象(int、float)
resize开销不大;但对大对象或带资源的类,反复resize可能引发大量构造/析构,比reserve + push_back慢数倍
capacity 不等于 size,但 capacity 为 0 时 size 必为 0
这是最常被忽略的底层约束:空 vector 的 capacity() 可能是 0(如刚构造未 reserve),此时任何 push_back 都强制首次分配;而 resize(0) 不清 capacity,只是把 size 归零。
立即学习“C++免费学习笔记(深入)”;
- 验证方式:
std::vector<int> v; assert(v.size() == 0 && v.capacity() == 0);</int>在某些标准库实现下成立 - 容易踩的坑:在循环里反复
resize(0)以为能“重用内存”,但若中间有人调过shrink_to_fit()或 vector 被移动过,capacity 可能已丢失 - 真实建议:如果真要复用 vector 且在意性能,用
clear()(保 capacity)+reserve(确保足够)比反复resize更可控
push_back 前,心里得快速过一遍:这次扩容代价我担不担得起?











