std::fill是清空int arr[100]等内置数组的首选,类型安全且编译器可优化;memset仅适用于pod类型,须传字节数如sizeof(arr),传指针或错误大小会导致越界或未清空。

用 std::fill 或 memset 清空内置数组最直接
对 int arr[100] 这类 C 风格数组,std::fill 是首选:它类型安全、可读性强,且编译器通常能优化成高效指令。比如 std::fill(arr, arr + 100, 0) 就把全部元素设为 0。
memset 更底层,只适用于 POD 类型(如 int、char),且必须传入字节数:memset(arr, 0, sizeof(arr))。别写成 sizeof(arr*) 或漏掉 sizeof——这是常见错误,会导致部分内存未清空或越界。
- 如果数组是局部变量,
sizeof(arr)正确;若是函数参数(退化为指针),sizeof(arr)就只剩指针大小,必须额外传长度 -
std::fill在模板推导失败时会报错,比memset的静默错误更容易定位
std::vector 用 clear() 不等于清内存
vec.clear() 只销毁元素并重置 size() 为 0,但底层存储(capacity())通常保留。这意味着内存没释放,再次 push_back 时可能复用旧空间。
真要释放内存,得配合 swap 技巧:std::vector<int>(vec).swap(vec)</int>,或 C++11 起更简洁的 vec.shrink_to_fit()(注意:后者是“请求”,不保证执行)。
-
clear()后vec.data()可能仍指向原地址,别假设内存已归零 - 若存的是自定义类型,
clear()会调用每个元素的析构函数;而memset直接覆写内存,对非 POD 类型是未定义行为
结构体数组清空要注意成员类型
含非 POD 成员(如 std::string、std::vector)的结构体数组,不能用 memset。例如:
struct S { std::string s; int x; };
S arr[10];
// ❌ 错误:破坏 string 内部指针
memset(arr, 0, sizeof(arr));
// ✅ 正确:逐个赋值或用 std::fill + 默认构造
std::fill(arr, arr + 10, S{});
S{} 调用默认构造,确保每个 std::string 处于有效状态;而 memset 把 s 的内部指针全设为 0,后续访问会崩溃。
- 即使结构体所有成员都是 POD,只要未来可能加非 POD 字段,就别依赖
memset - 用
std::fill配合S{}更易维护,且编译期就能检查是否可默认构造
清空不是重置:区分逻辑清空与内存归零
“清空”在业务中常指恢复初始状态,未必是填 0。比如布尔数组可能需全设为 false,浮点数组可能是 NaN 或 0.0,枚举数组应设为合法首值而非任意整数。
- 用
std::fill时,第二个参数必须是目标类型的合法值,别想当然用0替代所有类型 - 对
std::array,可用arr.fill(value)(C++11 起),比std::fill少写长度,也更直观 - 多维数组(如
int a[3][4])不能直接std::fill(a, a+3, ...),得展平处理或嵌套循环
真正麻烦的从来不是“怎么填”,而是填什么值才算“清空”——这取决于数据语义,而不是语法能不能跑通。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











