memset的使用

memset

memset是内存初始化函数

最简单的调用是将一个数组清零

const int maxn = 1024;
int a[maxn];
memset(a, 0, sizeof(a));  // a[0]=a[1]=a[...]=0;
  • sizeof(a) = maxn * 4 = 4096;
  • 表示的是将数组首地址a开始往后的4096个字节都设置为0

memset常见误区

  1. memset实现原理是根据字节来设置的

比如对于字节数组char a[100],将所有字节都设置为5,就可以调用:

​ memset(a, 5, sizeof(a));

但是,对于int b[100],也采用这种方法,就会导致错误:

​ memset(b, 5, sizeof(b));

得到 b 数组中元素的值为 84215045;

为什么?

我们将b数组元素转换成二进制得到:

( 00000101 00000101 00000101 00000101) 2

因为int占据了4个字节,memset是按字节来设置的,把每个字节都设置成了5,转换成十进制就成了84215045

  1. 堆内存不可直接 sizeof 取首地址

在堆上申请了一个数组空间,并且想要给它初始化,调用如下:

const int maxn = 1024;
int *p = new [maxn];
memset(p, 0, sizeof(p));

这里进入了另一个误区,因为 p 在这里虽然是数组首地址,但是它扮演的角色更多的其实是个指针,所以在进行 sizeof 运算符操作的时候,取得的值并不是 4096,而是指针的大小;

正确做法是:

const int maxn = 1024;
int *p = new [maxn];
memset(p, 0, maxn * sizeof(int));
  1. 传参数组不可直接 sizeof 取首地址

对传参为数组的数据进行 memset,调用如下:

void fun(int a[maxn]) {
    memset(a, 0, sizeof(a));
}

这里调用同样是错误的,因为当数组作为传参的时候,这里的 a 已经退化为指针,所以同样不能用 sizeof 数组首地址来取大小

正确做法是:

void fun(int a[maxn]) {
    memset(a, 0, maxn * sizeof(int));
}

当然,当传参是结构体指针的时候也是如此。

上一篇:冒泡排序(C++)


下一篇:悠漓带你浅谈C语言(数据类型)