reserve不改变size只影响capacity,它预先分配至少指定大小的内存但不构造元素,因此size不变而capacity≥请求值,错误访问未构造位置会导致未定义行为。

reserve 不改变 size,只影响 capacity
reserve 的作用是提前为 vector 的内部动态数组分配至少指定大小的内存,但它**不会构造任何元素**,因此调用后 vector::size() 不变,vector::capacity() 会 ≥ 请求值。常见误解是以为 reserve(n) 后就能直接访问 v[0] 到 v[n-1] —— 实际会越界,因为这些位置根本没被构造。
典型误用场景:
- 写成
v.reserve(10); v[5] = 42;→ 未定义行为(UB) - 和
resize()混用,比如先reserve再循环 push_back 却没检查是否真需要扩容
什么时候调用 reserve 才真正提升性能
只有在你能预估最终元素数量、且后续操作以 push_back 为主时,reserve 才有明确收益。例如读取文件行数已知、解析固定长度数组、批量生成对象等。
关键判断点:
立即学习“C++免费学习笔记(深入)”;
- 如果元素总数波动大(比如用户交互式追加),
reserve可能浪费内存或起反作用 - 若后续主要用
insert在中间插入,reserve对整体性能帮助有限,因为移动成本仍在 - 对小对象(如
int)效果明显;对大对象(含深拷贝的类),避免多次 realloc + copy 的收益更突出
示例:读取 1000 行文本前调用 v.reserve(1000),可避免 vector 多次按 1.5 倍增长导致的 7–10 次内存重分配与元素拷贝。
reserve 和 resize 的核心区别必须分清
reserve(n) 是“我打算塞最多 n 个,你先把地圈好”;resize(n) 是“我现在就要 n 个,不够的给我默认构造出来”。两者语义完全不同,不能互相替代。
常见混淆表现:
- 想初始化 100 个零值
int,写了v.reserve(100)→ 结果v.size() == 0,遍历时直接崩溃 - 正确做法是
v.resize(100)或v.assign(100, 0) - 若既要空间又要初值,且知道数量稳定,可
v.reserve(100); v.resize(100),但注意resize可能触发默认构造(对无默认构造函数的类型不适用)
reserve 的实际调用时机与陷阱
最安全的调用点是在所有元素插入开始前、且数量可预测时。但要注意几个隐性坑:
-
reserve不保证只分配一次 —— 如果请求容量小于当前capacity,它可能什么也不做;但如果系统内存碎片严重,即使满足请求也可能触发新分配 - 调用
shrink_to_fit()后再reserve,某些 STL 实现会多一次释放+重分配 - 多线程环境下,
reserve本身是线程安全的(不修改元素),但若其他线程同时push_back,仍需同步 - 对自定义分配器的
vector,reserve行为依赖分配器实现,未必完全按预期增长
真正容易被忽略的是:reserve 解决不了迭代器失效问题。只要发生 reallocation(包括由 reserve 主动触发的那次),原有迭代器、指针、引用全部失效 —— 这点和 resize 不同,后者在不扩容时保持有效性。










