c++oding="utf-8" ?>
clear()仅清空元素不释放内存,capacity不变;可靠缩容需用swap(vector{}).swap(vec)或c++11后clear()+shrink_to_fit()(后者仅为建议)。

clear() 只清内容,不释放内存
clear() 的作用是调用每个元素的析构函数,并把 size() 设为 0,但底层分配的内存(capacity())完全不变。这意味着反复 clear() 后再 push_back(),不会触发新内存分配,但也会持续占用本可释放的内存。
常见错误现象:程序长时间运行后内存占用居高不下,用 valgrind 或 taskmgr 观察发现 capacity() 巨大但 size() 常为 0 —— 很可能就是只用了 clear()。
- 适用场景:确定后续会频繁增删、且数据量波动不大,想避免反复分配
- 不适用场景:临时容器、函数内局部 vector、需显式归还内存给系统
- 验证方式:
vec.size()为 0 时检查vec.capacity()是否仍很大
swap(vector{}).clear() 是 C++11 前主流缩容法
利用临时右值 vector 与原 vector 交换内部指针,再让临时对象自动析构,从而真正释放内存。写法为:vector<int>().swap(vec)</int> 或更清晰的 vec.swap(vector<int>())</int>。
注意:该技巧依赖 move 语义或 copy-swap 惯用法,在 C++11 前广泛使用;C++11 起推荐用 shrink_to_fit(),但它的行为是“建议而非保证”。
-
swap()后vec.capacity()一定变为 0(或极小值),内存立即归还堆管理器 - 不能写成
vector<int>{}.swap(vec)</int>—— 临时对象是纯右值,无法绑定非 const lvalue 引用,编译失败 - 若 vector 元素类型析构开销大,
swap()本身几乎零成本,比遍历 destroy 更安全
shrink_to_fit() 不保证缩容,但语义更清晰
shrink_to_fit() 是 C++11 引入的成员函数,语义上请求容器“尽可能减少容量”,但标准只要求它“不改变元素”,是否真释放内存由实现决定(libc++ 通常会,libstdc++ 在某些版本中可能忽略)。
常见错误现象:调用 vec.shrink_to_fit() 后 vec.capacity() 没变,误以为函数失效 —— 实际是实现未响应请求。
- 必须配合
clear()使用:vec.clear(); vec.shrink_to_fit(); - 返回 void,无法判断是否成功;如需强保证,请回退到
swap()方案 - 在内存敏感场景(如嵌入式、高频批处理),别依赖它做资源回收依据
reserve() 和 shrink_to_fit() 的对称性陷阱
reserve(n) 确保容量 ≥ n,会主动分配;而 shrink_to_fit() 是被动请求,不强制。二者看似对称,实则权力不对等 —— 前者是命令,后者只是建议。
容易被忽略的地方:有人误以为 shrink_to_fit() 类似于 “reverse reserve”,甚至尝试 vec.reserve(0) 来缩容,但这是非法操作(reserve(0) 允许,但不释放内存,C++ 标准明确说明它不改变 capacity)。
-
reserve(0)是合法调用,但效果等同于无操作 - 真正缩容只有两条可靠路径:①
swap技巧,② C++20 起部分实现支持的vec = {}(依赖移动赋值优化) - 若 vector 是类成员且需频繁重置,考虑在构造函数里用
vector<t>().swap(*this)</t>初始化,避免首次分配残留
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











