【问题标题】:Memory layout in memsetmemset 中的内存布局
【发布时间】:2017-02-14 06:34:59
【问题描述】:

我有这个 “buggy” 代码:

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

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

【问题讨论】:

  • 我不明白你的问题,因为你在第一行已经有了答案。 memset 将每个字节设置为 1 = 0x01,因为 int 通常为 4 个字节 4 个字节将设置为 0x01010101。你能澄清一下你在内存布局方面的理解弱点吗?这可能更有帮助。
  • 请记住 sizeof(arr) == 60(字节)而不是 15(整数)。
  • 是的,所以我知道我正在为每个 1 字节分配一个 4 字节值 1,如何将 4 字节值分配给单个字节? @acraig5075
  • 你确定你真正的问题不是stackoverflow.com/questions/13477281/…
  • 不。不。这就是我写“buggy”的原因。 @UmNyobe

标签: c++ hex memset


【解决方案1】:

如果我相信手册页

memset() 函数将值 c(转换为无符号字符)的 len 个字节写入字符串 b。

在您的情况下,它将 0x00000001(作为 int)转换为 0x01(作为无符号字符),然后用该值填充内存的每个字节。您可以将其中的 4 个放入一个 int 中,即每个 int 将变为 0x01010101。

如果你有 4,它将被转换为无符号字符 0x04,每个 int 将填充 0x04040404。

这对你有意义吗?

【讨论】:

    【解决方案2】:

    memset 所做的是

    将值 ch 转换为 unsigned char 并将其复制到 dest 指向的对象的前 count 个字符中。

    因此,首先将您的值 (1) 转换为占用 1 个字节的 unsigned char,因此将是 0b00000001。然后 memset 将用这些值填充整个数组的内存。由于 int 在您的机器上占用 4 个字节,因此数组中每个 int int 的值将是 00000001000000010000000100000001,即 16843009。如果您放置另一个值而不是 1,则数组的内存将被填充取而代之。

    【讨论】:

      【解决方案3】:

      注意memset 将其第二个参数转换为一个字节的unsigned char。一个字节是八位,您将每个字节设置为值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

      【讨论】:

        猜你喜欢
        • 2016-01-17
        • 1970-01-01
        • 1970-01-01
        • 2018-08-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-21
        相关资源
        最近更新 更多