chatgpt对memset的介绍下
memset 是 C 标准库中的一个内存操作函数,定义在 <string.h> 头文件中。它用于将一块用户空间的内存区域的所有字节设置为指定的值,常用于初始化或清零内存。当然,内核空间中也有同名的函数,不过引入的头文件是<linux/string.h>,而不是<string.h>,并且运行于内核空间中的memset是对内核空间的内存进行操作的。
函数原型
#include <string.h>
void *memset(void *s, int c, size_t n);
参数说明
s:指向要填充的内存块的起始地址。c:要设置的字节值(int类型,但会转换为unsigned char)。n:要填充的字节数。
返回值
返回 s 指向的内存块的起始地址。
功能
- 用
c填充s指向的n个字节。 - 通常用于初始化数组、结构体,或者清空内存区域。
示例
1. 初始化数组
#include <stdio.h>
#include <string.h>
int main() {
char buffer[10];
// 将 buffer 的所有字节设为 'A' (0x41)
memset(buffer, 'A', sizeof(buffer));
// 打印结果
for (int i = 0; i < 10; i++) {
printf("%c ", buffer[i]); // 输出:A A A A A A A A A A
}
printf("\n");
return 0;
}
2. 清零数组
#include <stdio.h>
#include <string.h>
int main() {
int arr[5] = {1, 2, 3, 4, 5};
// 将数组清零
memset(arr, 0, sizeof(arr));
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]); // 输出:0 0 0 0 0
}
printf("\n");
return 0;
}
注意:
memset(arr, 0, sizeof(arr))对于int数组有效,因为0的所有字节都是0。- 但
memset(arr, -1, sizeof(arr))不能保证arr变为-1,因为-1在int中可能是0xFFFFFFFF(取决于 CPU 架构)。
3. 清除结构体
#include <stdio.h>
#include <string.h>
struct Data {
int a;
char b;
double c;
};
int main() {
struct Data d = {100, 'X', 3.14};
// 清零结构体
memset(&d, 0, sizeof(d));
printf("a = %d, b = %c, c = %f\n", d.a, d.b, d.c); // 输出:a = 0, b = , c = 0.000000
return 0;
}
注意:
memset清零结构体时,所有成员的二进制值都变为0,对于char和int类型有效。- 但对浮点数和指针类型,最好用
= {0}来清零,而不是memset,因为某些平台上memset可能不会生成正确的0.0或NULL。
注意事项
1. memset 不能用于非 char 类型的初始化
memset 只能按字节填充。如果 memset(arr, 1, sizeof(arr)) 作用于 int 数组:
int arr[4];
memset(arr, 1, sizeof(arr));
可能的内存布局是:
0x01010101 0x01010101 0x01010101 0x01010101
但 1 的正确表示应为 0x00000001!
所以,memset 适用于 字符数组,但不适用于 int、float 等非字节类型的数组。
2. memset 不能清空动态分配的内存
如果使用 malloc() 申请的内存需要清零,推荐使用:
int *p = malloc(10 * sizeof(int));
memset(p, 0, 10 * sizeof(int)); // 清零
或者直接使用:
int *p = calloc(10, sizeof(int)); // `calloc` 自动清零
小结
memset用于填充内存,可用于清零数组、结构体等。- 适用于 字符数组、字节流等,但不适用于
int、float等非字节类型。 - 清零
int数组或结构体时,最好使用= {0}。 - 如果要初始化动态分配的内存,建议使用
calloc。
初始化int数组时要注意的地方
使用C++的函数memset()时要注意它的操作对象是每一个字节,由于一个int变量占据的空间不只1个节所,所以不能用它将int数组初始化为0和-1之外的其他值(除非该值高字节和低字节相同)。
比如我想利用它把int型数组的每一个元素的值全部置为88是不行的,测试代码如下:
#include <opencv2/opencv.hpp>
#include <iostream>
int main()
{
int bucket_size = 3;
int *bucket;
bucket = new int[bucket_size];
memset(bucket, 88, bucket_size * 4);
std::cout <<"bucket[0]的值为:"<< bucket[0] << std::endl;
return 0;
}
运行结果如下:

但因为char类型在内存中是只占一个字节的,所以是可以用函数memset()将char数组中的每一个元素置为88的,测试代码如下:
#include <opencv2/opencv.hpp>
#include <iostream>
int main()
{
int bucket_size = 3;
char *bucket;
bucket = new char[bucket_size];
memset(bucket, 88, bucket_size * 1);
std::cout <<"bucket[0]的值为:"<< bucket[0] << std::endl;
return 0;
}
运行结果如下:


可见结果和刚才说的一致。
本文介绍了C++函数memset的用途,特别强调了其用于初始化内存时的注意事项,如不能用于整数数组的全0或全非1值初始化,以及如何在char数组上使用。通过实例演示了不同类型的内存初始化结果差异。
286

被折叠的 条评论
为什么被折叠?



