【问题标题】:Storing integers in a malloc'd block在 malloc 块中存储整数
【发布时间】:2018-11-20 22:39:06
【问题描述】:

我正在研究 Pintos 第 4 部分,特别是用于 inode 数据结构的间接块。该块应该有 (512 / 4) = 128 个整数,指的是其中的其他磁盘扇区。我在我的 c 程序中做了一个小模拟,将模拟扇区写入 malloc 的模拟扇区,然后将其读回。为什么钥匙这么大?为什么不是 0、1、2、3、4。

#include <stdio.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>

int main(void) {

  void *mock_sector = malloc(512);
  for (uint32_t i = 0; i < 20; i++) {
    memset(mock_sector + i * sizeof(uint32_t), i, sizeof(uint32_t));
  }

  uint32_t key;
  for (uint32_t i = 0; i < 20; i++) {
    memcpy(&key, mock_sector + i * sizeof(uint32_t), sizeof(uint32_t));
    printf("Key is: %d\n", key);
  }

  return 0;
}

结果->

Key is: 0
Key is: 16843009
Key is: 33686018
Key is: 50529027
Key is: 67372036
Key is: 84215045
Key is: 101058054
Key is: 117901063
Key is: 134744072
Key is: 151587081
Key is: 168430090
Key is: 185273099
Key is: 202116108
Key is: 218959117
Key is: 235802126
Key is: 252645135
Key is: 269488144
Key is: 286331153
Key is: 303174162
Key is: 320017171

我什至可以看到我调用 memset 的地址正在增加。

0x18aa010 0x18aa014 0x18aa018 0x18aa01c 0x18aa020 0x18aa024 0x18aa028 0x18aa02c

【问题讨论】:

  • 但是您将数字的每个 byte 分配为等于(char)i。所以第一个数字是 0x00000000,第二个是 0x01010101,依此类推。
  • 你的 memset:不应该是 memset(mock_sector,0,sizeof *mock_sector); 吗?并且没有 for 循环!
  • 你为什么使用空指针?

标签: c


【解决方案1】:

手动进行指针运算,并使用 memset / memcpy 设置和获取您的值,这太疯狂了。正确方法:

((uint32_t *)mock_sector) [i] = i;

当然还有 malloc (128 * sizeof (uint32_t)),而不是 malloc (512)。

【讨论】:

  • 谢谢。真的很欣赏它
  • 或者更好:uint32_t *mock_sector = malloc(128 * sizeof(uint32_t)); 然后mock_sector[i] = i;
【解决方案2】:

如果我编译您的程序,但将 printf 中的格式说明符更改为 %.8X(基数 16)而不是 %d(基数 10),则输出为:

Key is: 00000000
Key is: 01010101
Key is: 02020202
Key is: 03030303
Key is: 04040404
Key is: 05050505
Key is: 06060606
Key is: 07070707
Key is: 08080808
Key is: 09090909
Key is: 0A0A0A0A
Key is: 0B0B0B0B
Key is: 0C0C0C0C
Key is: 0D0D0D0D
Key is: 0E0E0E0E
Key is: 0F0F0F0F
Key is: 10101010
Key is: 11111111
Key is: 12121212
Key is: 13131313

你现在看到模式和错误了吗?

memset 的第二个参数被强制转换为 unsigned char(即一个字节),即使它的类型为 int,如文档中的 here 所示。这意味着每个字节(不是每个uint32_t)都将填充i 的值转换为一个字节。

使用此代码写入您的数组:

memset(mock_sector, 0, 512);

for (uint32_t i = 0; i < 20; i++) 
{
    mock_sector[i * sizeof(uint32_t)] = i;
}

【讨论】:

  • memset(mock_sector + i * sizeof(uint32_t), i, sizeof(uint32_t));上面的答案说我为每个字节分配的数字等于 i 的 char。我只是不明白为什么。
  • @Nate memset 正在使用第三个参数将i 复制到目标地址处uint32_t 占用的每个单个字节;这就是我想说的。
  • 知道了。但我不是一个 4 字节的值(uint32)。所以它只复制 i 的第一个字节 4 次?
猜你喜欢
  • 2017-06-08
  • 1970-01-01
  • 2014-07-17
  • 2023-03-30
  • 1970-01-01
  • 2021-06-20
  • 2010-12-14
  • 1970-01-01
  • 2023-04-05
相关资源
最近更新 更多