memset中的内存布局

时间:2017-02-14 06:35:00

标签: c++ hex memset

我有“buggy”代码:

int arr[15];
memset(arr, 1, sizeof(arr));

memset将每个字节设置为1,但由于int通常为4字节,因此不会提供所需的输出。我知道数组中的每个int都会被初始化为0x01010101 = 16843009。由于我对十六进制值和内存布局的理解很弱(非常),有人可以解释为什么它被初始化为十六进制值吗?如果我说4代替1,将会是什么情况?

3 个答案:

答案 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 = 0x00b0001 = 0x1,您的最终值为0x01010101。使用memset(arr, 4, sizeof(arr));,您将获得0x04040404,使用12,您将获得0x0c0c0c0c