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]]