memset用于按字节填充内存,适合POD类型初始化;不适用于std::string等非POD对象,否则导致未定义行为;参数为地址、字节值(取低8位)、字节数;现代C++优先使用{}初始化、std::fill或智能指针。

memset 用来干啥?不是万能清零工具
memset 是 C 标准库函数,头文件 (C++ 中推荐),作用是按字节填充一块内存区域。它**不关心类型**,只认地址和字节数。所以它适合初始化 POD 类型(如 int、char、struct 里不含指针/虚函数/非平凡构造函数的),但对 std::string、std::vector 或含自定义构造函数的对象直接用 memset 会破坏对象状态,导致未定义行为。
基本用法:三个参数缺一不可
函数原型:void* memset(void* ptr, int value, size_t num);
-
ptr:目标内存起始地址,必须可写,且已分配(不能是野指针或未 new/malloc 的栈变量地址) -
value:要填入的**字节值**(注意:是int,但只取低 8 位,即value & 0xFF) -
num:要填充的**字节数**,不是元素个数
常见误用:memset(arr, 0, sizeof(arr)) 对数组有效,但 memset(ptr, 0, sizeof(ptr)) 只填了指针本身 4 或 8 字节,不是它指向的内容。
int arr[10]; memset(arr, 0, sizeof(arr)); // ✅ 正确:清空整个数组(40 字节)int p = new int[10]; memset(p, 0, sizeof(p)); // ❌ 错!只清了指针变量 p 占的字节 memset(p, 0, 10 sizeof(int)); // ✅ 正确:清 10 个 int(40 字节)
初始化为 0 和 -1 是安全的,其他值要小心
因为 memset 按字节操作,所以:
立即学习“C++免费学习笔记(深入)”;
-
memset(p, 0, n)→ 所有字节为0x00,对int、float、指针等,结果通常是预期的“零值”(如0、0.0f、nullptr) -
memset(p, -1, n)→ 所有字节为0xFF,对int(补码)是-1,对unsigned int是最大值,但对float是 NaN,对指针是非法地址 -
memset(p, 1, n)→ 每个字节都是0x01,int变成0x01010101(即 16843009),不是你想的“每个 int 都是 1”
想把 int 数组全设为 1?用 std::fill 或循环:std::fill(arr, arr + 10, 1);
现代 C++ 更推荐什么替代方案?
除非处理底层内存(如 socket 缓冲区、结构体二进制序列化),否则优先用类型安全方式:
- 栈数组:直接
int arr[10]{};(值初始化,全零) - 堆数组:
auto p = std::make_unique或(10); std::vector(10); - 结构体:用默认成员初始化器或构造函数,避免裸
memset - 需要全零时:
std::fill_n(p, n, T{});(T{}是T的零值)
真正要用 memset 的地方,往往已经绕不开 C ABI 或性能敏感的 raw buffer 场景——这时候务必确认目标内存是 POD,且你清楚自己在按字节操作。










