我有“buggy”代码:
int arr[15];
memset(arr, 1, sizeof(arr));
memset
将每个字节设置为1,但由于int
通常为4字节,因此不会提供所需的输出。我知道数组中的每个int
都会被初始化为0x01010101 = 16843009
。由于我对十六进制值和内存布局的理解很弱(非常),有人可以解释为什么它被初始化为十六进制值吗?如果我说4代替1,将会是什么情况?
答案 0 :(得分:2)
如果我信任该手册页
memset()函数将值为c的len个字节(转换为unsigned char)写入字符串b。
在您的情况下,它会将0x00000001(作为int)转换为0x01(作为无符号字符),然后使用此值填充内存的每个字节。你可以在int中拟合其中的4个,也就是说,每个int将变为0x01010101。
如果你有4,它将被转换为unsigned char 0x04,每个int将填充0x04040404。
这对你有意义吗?
答案 1 :(得分:1)
memset做的是
将值ch转换为unsigned char并将其复制到dest指向的对象的每个第一个计数字符中。
所以,首先你的值(1
)将被转换为unsigned char,占用1个字节,因此它将是0b00000001
。然后memset将用这些值填充整个数组的内存。由于int
在您的计算机上占用4个字节,因此数组中每个int
的值为00000001000000010000000100000001
,即16843009.如果您放置另一个值而不是1
,数组的内存将填充该值。
答案 2 :(得分:0)
请注意,memset
将其第二个参数转换为unsigned char
,即一个字节。一个字节是8位,您可以将每个字节设置为值1
。所以我们得到
0b00000001 00000001 00000001 00000001
或十六进制,
0x01010101
或十进制数16843009
。为什么这个价值?因为
0b00000001000000010000000100000001 = 1*2^0 + 1*2^8 + 1*2^16 + 1*2^24
= 1 + 256 + 65536 + 16777216
= 16843009
每组四个二进制数字对应一个十六进制数字。由于0b0000
= 0x0
和0b0001
= 0x1
,您的最终值为0x01010101
。使用memset(arr, 4, sizeof(arr));
,您将获得0x04040404
,使用12
,您将获得0x0c0c0c0c
。