Windows 中的奇怪指针行为
Weird pointer behaviour in Windows
我一直在尝试理解指针,特别是指针[i] 表示法,它等同于 *(pointer + i),即解引用下一个地址的值,所以如果它是一个 int 指针下一个 4 字节地址。我尝试了 运行 下面的代码:
#include <stdio.h>
int main(void){
int x = 10;
int y = 20;
int* z = &y;
printf("address of x: %u ", &x);
printf("address of y: %u", &y);
printf("value at address: %u \n", *(z+1));
}
我注意到 'y' 在 'x' 之前存储了 4 个字节,并认为我可以 return 通过 z[1] 或 * 存储在 x 地址的值(z+1),效果很好。
然而,当我删除前 2 个 printf 时,我最终输出的是地址而不是实际值 (10),这是这种情况的代码:
#include <stdio.h>
int main(void){
int x = 10;
int y = 20;
int* z = &y;
printf("value at address: %u \n", *(z+1));
}
我假设 *(z+1) 不再指代与变量 'x' 相同的内存区域,但我很困惑为什么代码中的这种变化会导致这种情况。
一开始我以为是一次性的,所以我试了很多次,每次都得到相同的结果。
更令人困惑的是代码在 ubuntu 和 macOS 上如何按预期工作,但在 windows.
上却没有
任何有关此的帮助都将非常有用,谢谢。
这里我只能回答你的部分问题,并提出我的看法
观察。
这里是修改后的代码。
#include <stdio.h>
int main(void) {
int x = 10;
int y = 20;
int *intp = &y;
// printf("address of x is %p.\n", &x);
// printf("address of y is %p.\n", &y);
printf("*(intp + 1) is %u.\n", *(intp + 1));
printf("*(intp) is %u.\n", *(intp));
printf("*(intp - 1) is %u.\n", *(intp - 1));
printf("difference of addresses: &x - &y = %d.\n", &x - &y);
return 0;
}
我得到了 *(intp)
一致的结果,
*(intp - 1)
和 &x - &y
,而
*(intp + 1)
会改变。其中一个输出是
*(intp + 1) is 2028820428.
*(intp) is 20.
*(intp - 1) is 10.
difference of addresses: &x - &y = -1.
但是,如果我使用 &x
、
注释掉该行
// printf("difference of addresses: &x - &y = %d.\n", &x - &y);
输出会一致,如下
*(intp + 1) is 10.
*(intp) is 20.
*(intp - 1) is 0.
我的想法是,在我的 gcc 10.2.0
上 Linux,
- 第一种情况,当使用
&x
时,x
是
存储在比 y
低 4 个字节的地址。作为
int
在我的电脑上是 4 个字节,&x - &y
总是 -1
.
- 第二种情况,不用
&x
时,x
存储在比 y
高 4 个字节的地址。
所以编译器确实设置了 space 来存储 x
和
y
,即使未使用 x
。但是我
不知道为什么他们的立场在这两种情况下会有所不同。编译器
可以尝试优化代码,但我对此知之甚少
此外,如果您想尝试使用 gdb
来测试
地址,你可以试试
gcc -g thecode.c
gdb a.out
(gdb) break main
(gdb) run
(gdb) p &x
(gdb) p &y
(gdb) p &x + 1
(gdb) step
(gdb) (press enter directly to use the last same command...)
(gdb) quit
我一直在尝试理解指针,特别是指针[i] 表示法,它等同于 *(pointer + i),即解引用下一个地址的值,所以如果它是一个 int 指针下一个 4 字节地址。我尝试了 运行 下面的代码:
#include <stdio.h>
int main(void){
int x = 10;
int y = 20;
int* z = &y;
printf("address of x: %u ", &x);
printf("address of y: %u", &y);
printf("value at address: %u \n", *(z+1));
}
我注意到 'y' 在 'x' 之前存储了 4 个字节,并认为我可以 return 通过 z[1] 或 * 存储在 x 地址的值(z+1),效果很好。
然而,当我删除前 2 个 printf 时,我最终输出的是地址而不是实际值 (10),这是这种情况的代码:
#include <stdio.h>
int main(void){
int x = 10;
int y = 20;
int* z = &y;
printf("value at address: %u \n", *(z+1));
}
我假设 *(z+1) 不再指代与变量 'x' 相同的内存区域,但我很困惑为什么代码中的这种变化会导致这种情况。
一开始我以为是一次性的,所以我试了很多次,每次都得到相同的结果。
更令人困惑的是代码在 ubuntu 和 macOS 上如何按预期工作,但在 windows.
上却没有任何有关此的帮助都将非常有用,谢谢。
这里我只能回答你的部分问题,并提出我的看法 观察。
这里是修改后的代码。
#include <stdio.h>
int main(void) {
int x = 10;
int y = 20;
int *intp = &y;
// printf("address of x is %p.\n", &x);
// printf("address of y is %p.\n", &y);
printf("*(intp + 1) is %u.\n", *(intp + 1));
printf("*(intp) is %u.\n", *(intp));
printf("*(intp - 1) is %u.\n", *(intp - 1));
printf("difference of addresses: &x - &y = %d.\n", &x - &y);
return 0;
}
我得到了 *(intp)
一致的结果,
*(intp - 1)
和 &x - &y
,而
*(intp + 1)
会改变。其中一个输出是
*(intp + 1) is 2028820428.
*(intp) is 20.
*(intp - 1) is 10.
difference of addresses: &x - &y = -1.
但是,如果我使用 &x
、
// printf("difference of addresses: &x - &y = %d.\n", &x - &y);
输出会一致,如下
*(intp + 1) is 10.
*(intp) is 20.
*(intp - 1) is 0.
我的想法是,在我的 gcc 10.2.0
上 Linux,
- 第一种情况,当使用
&x
时,x
是 存储在比y
低 4 个字节的地址。作为int
在我的电脑上是 4 个字节,&x - &y
总是-1
. - 第二种情况,不用
&x
时,x
存储在比y
高 4 个字节的地址。
所以编译器确实设置了 space 来存储 x
和
y
,即使未使用 x
。但是我
不知道为什么他们的立场在这两种情况下会有所不同。编译器
可以尝试优化代码,但我对此知之甚少
此外,如果您想尝试使用 gdb
来测试
地址,你可以试试
gcc -g thecode.c
gdb a.out
(gdb) break main
(gdb) run
(gdb) p &x
(gdb) p &y
(gdb) p &x + 1
(gdb) step
(gdb) (press enter directly to use the last same command...)
(gdb) quit