-1

假设我们有这个:

int main()
{

    int32_t* value = (uint32_t*)malloc(sizeof(uint32_t));
    uint32_t array[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};

    *value = *(uint32_t*)((char*)array + 8);

    printf("Value is: %d\n", *value);

    return 0;
}

这种情况下的值是 3。为什么会这样呢?如果我们将 uint32_t 转换为 char,这是否意味着一个 char 在 uint32_t 中是 4 字节,因此

array[9] = {0, 4, !!8!!, 12, 16, 20, 24, 28, 32};

有人可以尝试解释一下吗?

4

2 回答 2

2

初始化数组时,每个初始化程序都会设置数组的一个元素,而不管每个元素占用多少字节。

您的机器可能正在使用 little-endian 字节排序。这意味着array在内存中看起来像这样:

-----------------------------------------------------------------
| 1 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | 3 | 0 | 0 | 0 | 4 | 0 | 0 | 0 | ...
-----------------------------------------------------------------

|      [0]      |      [1]      |      [2]      |      [3]      | ...

每个类型的值uint32_t都是 4 个字节长,最低有效字节在前。

当您这样做时(char*)array,将array(转换为指针)转换为 a char *,因此 a 上的任何指针算术都会char *将地址增加 a 的大小char,即 1。

所以(char*)array + 8在这里指出:

(char*)array + 8 ------------------
                                  v
-----------------------------------------------------------------
| 1 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | 3 | 0 | 0 | 0 | 4 | 0 | 0 | 0 | ...
-----------------------------------------------------------------

|      [0]      |      [1]      |      [2]      |      [3]      | ...

然后将该指针转换为 auint32_t *并取消引用,因此它读取值 3。

于 2018-08-24T15:19:46.780 回答
1

可能的内存布局

您创建array[9]的需要 36 个字节。它存储在内存中,如第一行所示。3按照我的说法存储(它因编译器而异)。

将其类型转换为 char 内存后,如第 2 行所示。

现在,如果您添加 8,它将进入第 8 位,这意味着 之后02,为什么,因为,(char*)array + 8被视为type+8。这里typechar。所以它只移动了 8 个字节。

然后将内存从 8 到 35 类型转换为 uint32_t 并将第一个值存储在*value. 所以3只会。

于 2018-08-24T15:21:51.673 回答