C/C++的标准库函数memset的介绍(初始化或清零一块内存区域)

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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,因为 -1int 中可能是 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,对于 charint 类型有效。
  • 但对浮点数和指针类型,最好用 = {0} 来清零,而不是 memset,因为某些平台上 memset 可能不会生成正确的 0.0NULL

注意事项

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 适用于 字符数组,但不适用于 intfloat 等非字节类型的数组。

2. memset 不能清空动态分配的内存

如果使用 malloc() 申请的内存需要清零,推荐使用:

int *p = malloc(10 * sizeof(int));
memset(p, 0, 10 * sizeof(int)); // 清零

或者直接使用:

int *p = calloc(10, sizeof(int)); // `calloc` 自动清零

小结

  • memset 用于填充内存,可用于清零数组、结构体等。
  • 适用于 字符数组、字节流等,但不适用于 intfloat 等非字节类型。
  • 清零 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;
}

运行结果如下:
在这里插入图片描述
在这里插入图片描述
可见结果和刚才说的一致。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值