C 代码指针谜题

标签 c pointers segmentation-fault 64-bit puzzle

我正在查看同学发布的一些代码,为了这个示例,它已被简化:

int main()
{
    int n = 0x4142;
    char * a = (char *) &n;

    char * b1 = (((char *) &n) + 1);
    char * b2 = (((int) &n) + 1);

    printf("B1 Points to 0x%x - B2 Points to 0x%x\n", b1, b2);

    printf("A Info - 0x%x - %c\n", a, *a);
    printf("B1 Info - 0x%x - %c\n", b1, *b1);
    printf("B2 Info - 0x%x - %c\n", b2, *b2);

   return 0;
}

输出为:

B1 Points to 0xcfefb03d - B2 Points to 0xcfefb03d
A Info - 0xcfefb03c - B
B1 Info - 0xcfefb03d - A
Segmentation fault (core dumped)

尝试打印 b2 时出现段错误。然而我认为输出应该包含以下行而不是段错误:

B2 Info - 0xcfefb03d - A

为什么会出现这样的情况呢? b1和b2都是char*,并且它们都指向同一个地址。这是在 64 位机器上,其中 sizeof(char*) == 8 和 sizeof(int) == 4(如果重要的话)。

最佳答案

but it segfaults on a 64bit computer

可能的原因是,在您的平台上,指针是 64 位,而整数是 32 位。因此,当您将指针转换为 int 时,您会丢失信息。

我的编译器特别警告这一点:

test.c:7:19: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]

使用以下程序很容易看到这一点:

#include <stdio.h>

int main()
{
   char *s = "";
   printf("%p %p\n", s, (char*)(int)s);
   return 0;
}

在我的计算机上,这会打印两个不同的地址(第二个地址的顶部位被截掉)。

what I don't quite understand is that both b1 and b2 are char*, and they both point to the same address

实际上,它们并不指向同一个地址。您的 printf() 格式说明符都是错误的。第一个 printf() 应该是:

printf("B1 Points to %p - B2 Points to %p\n", b1, b2);

当您运行此命令时,您会发现地址不同。

关于C 代码指针谜题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15859667/

相关文章:

c - C 中从命令行输入的字符串或字符

c++ - 将指针传递给函数

c - 使用 fscanf 读取文件在 c 中不起作用?

c++ - 调用 `gdk_rgba_to_string()` 时出现段错误

c - strcpy(m+1,m) 的不可预测行为

C文法复合语句

c - 我的 X11 代码有什么问题?

c - 检查字符数组是否为零的快速方法

c++ - 指针算术(不是一个问题,而是一种测验)

c++ - 在公共(public)方法中插入映射(私有(private)属性)后出现段错误