我正在查看同学发布的一些代码,为了这个示例,它已被简化:
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/