c - 了解指针(在 C 中): converting int pointer to char and changing values

标签 c pointers malloc

我有以下代码,处理 C 中的指针

void
f(void)
{
    int a[4];
    int *b = malloc(16);
    int *c;
    int i;

    printf("1: a = %p, b = %p, c = %p\n", a, b, c);

    c = a;
    for (i = 0; i < 4; i++)
         a[i] = 100 + i;

    c[0] = 200;
    printf("2: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
           a[0], a[1], a[2], a[3]);

    c[1] = 300;
    *(c + 2) = 301;
    3[c] = 302;
    printf("3: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
           a[0], a[1], a[2], a[3]);

    c = c + 1;
    *c = 400;
    printf("4: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
           a[0], a[1], a[2], a[3]);

    c = (int *) ((char *) c + 1);

    *c = 500;
    printf("5: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
           a[0], a[1], a[2], a[3]);

    b = (int *) a + 1;
    c = (int *) ((char *) a + 1);
    printf("6: a = %p, b = %p, c = %p\n", a, b, c);
}

int
main(int ac, char **av)
{
    f();
    return 0;
}

输出:

1: a = 0x7fff5fbff710, b = 0x1003002e0, c = 0x100000000
2: a[0] = 200, a[1] = 101, a[2] = 102, a[3] = 103
3: a[0] = 200, a[1] = 300, a[2] = 301, a[3] = 302
4: a[0] = 200, a[1] = 400, a[2] = 301, a[3] = 302
5: a[0] = 200, a[1] = 128144, a[2] = 256, a[3] = 302
6: a = 0x7fff5fbff710, b = 0x7fff5fbff714, c = 0x7fff5fbff711
Program ended with exit code: 0

我明白为什么 a[1] 是 128144(当我们将 int 指针转换为 char +1 并覆盖 500 时,我们向前移动了一个字节),但我不明白为什么 a[2] 是 256 [第一位将被覆盖,但不会给出 256]。我将非常感谢帮助!提前致谢:)

最佳答案

简短回答:您修改了 c,因此它不再具有 4 字节整数对齐,并将其设置为 500 修改了两个数组元素。此外,未对齐的访问通常是不允许的,并且会在某些系统上导致对齐错误。

长答案:在第 4 步,a[1] 包含 0x00000190,即 400,a[2] 包含 0x0000012D,即 301。

假设 a[0] 从内存地址 0 开始。这是字节在 little-endian 系统中的排列方式(这里的字节顺序非常重要) ,从左到右从 0 到 15:

ADDR: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F  
DATA: C8 00 00 00 90 01 00 00 2D 01 00 00 2E 01 00 00 

在第 5 步,您通过转换为 char *c 未对齐一个字节,因此它指向地址 05 04。您将值 500 (0x000001F4) 分配给它,它会覆盖 05-08 的字节,从而导致此内存:

ADDR: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F  
DATA: C8 00 00 00 90 F4 01 00 00 01 00 00 2E 01 00 00  

当您读取 a[1] 时,您会得到 0x0001F490,即 128144。
当您读取 a[2] 时,您会得到 0x00000100,即 256。

关于c - 了解指针(在 C 中): converting int pointer to char and changing values,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42448526/

相关文章:

c - 为什么x等于10?

C++:严格别名与 union 滥用

c++ - 用 C 封装 C++ 接口(interface)

c - 如何修复我的代码以从函数返回指向结构的指针

c - 使用链表和字符数组时出现段错误

c - 从字符串数组中删除字符串 (C)

c - memmove 不复制缓冲区的所有内容 - C

c - c中的指针有问题

c - malloc 用于指向结构的指针

c - 为什么调用 strcpy() 会导致我的源字符串发生变化?