跳到主要内容

memset的一个坑

· 阅读需 3 分钟

为数组赋初值是很常见的操作,如果不赋初值,默认就是随机值:

int main() {
int a[5];
return 0;
}

如果想将a中的元素全部赋为0,第2行可以写为:

int a[5]{0};

这是C++ 11的写法,在此之前应写为:

int a[5] = {0};

如果想把第0个元素赋为1,其余赋为0呢,那么可以写为:

int a[5]{1};

注意这里并不是把数组的元素全部设为1。

如果把数组定义为全局变量,那么会在堆中创建,会初始化为默认值:

int a[5];
int main() {
return 0;
}

此时数组a的元素会全部初始化为0。

如果想把数组重置为全0,那么可以用memset

memset(a, 0, sizeof a);

那么,怎么把数组里所有元素全部赋初值1呢?

一个很容易犯的错误写法就是:

memset(a, 1, sizeof a);

若如此做,a中的元素都是16843009。为什么会这样呢?

这是memset的函数原型:

void *memset(void *s, int c, size_t n);

其实memset是给字节数组赋初值的!memset会对s 逐字节填充 值c。由于int有4字节,所以上面那个错误写法导致每个元素被写为:

0x01010101

转为十进制也就是16843009。

所以,还是用循环吧……这时,有点怀念Python的给list赋初值的写法:

a = [1] * 5

不过,别用list赋初值,因为是浅拷贝:

>>> a = [[]] * 5
>>> a[0].append(3)
>>> a
[[3], [3], [3], [3], [3]]