gpt4 book ai didi

C 编译器重定位与另一个变量重叠的指针

转载 作者:太空宇宙 更新时间:2023-11-04 06:35:09 25 4
gpt4 key购买 nike

我正在做一些实验来了解 C 如何在堆栈上分配变量。我在使用以下代码时出现了一些奇怪的行为。 C 似乎在向下增长堆栈,因此在下面的示例中,char c 被分配到 short s 之前的字节中。然后我创建一个 int 指针 bigRandP 并将它指向 c 占用的相同位置,因此它看到的“int”与 s 占用的堆栈空间重叠。然后,我尝试将某些内容分配给 int 指针引用的位置。

unsigned short nameSum = 0;
unsigned char smallRand = 0;
unsigned int* bigRandP;

//The "int" pointed to by iP should overlap s
bigRandP = (unsigned int*)(&smallRand);
printf("%p %p %p\n", &nameSum, &smallRand, bigRandP);
printf("%u %u %u\n", smallRand, nameSum, *bigRandP);
*bigRandP = 0;
printf("%p %p %p\n", &nameSum, &smallRand, bigRandP);
printf("%u %u %u\n", smallRand, nameSum, *bigRandP);

0028FF1A 0028FF19 0028FF19
0 0 419430400
0028FF1A 0028FF19 0028FF00
0 0 4210788

打印的结果很有趣。不仅赋值失败(bigRandP 指向的 int 未设置为 0),int 指针本身也悄无声息地重定位指向堆栈下方的其他地方。到底是怎么回事?这是 C 编译器阻止我用重叠指针覆盖其他变量的方法吗?

最佳答案

bigRandP 是指向 unsigned int 的指针。

您将它指向一个unsigned char 对象,然后您修改 bigRandP 指向的unsigned int 对象到。

显然 smallRandbigRandP 在内存中彼此靠近存储。通过尝试修改 1 字节对象的 sizeof (unsigned int) 字节,您破坏了指针对象本身的一部分。

底线:您的程序的行为未定义。

此外,虽然这可能与您看到的行为无关,但 %p 格式需要一个 void* 参数。如果你想打印一些其他类型的指针,你应该把它转换成void*:

printf("%p %p %p\n", (void*)&nameSum, (void*)&smallRand, (void*)bigRandP);

在所有指针都具有相同表示的系统上,不管有没有强制转换,它都可能“工作”,但是带有强制转换的版本在所有系统上都更正确。

关于C 编译器重定位与另一个变量重叠的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15841478/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com