微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Windows 中奇怪的指针行为

如何解决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 个字节,并认为我可以通过 z[1] 或 *(z+1) 返回存储在 x 地址的值,这很好用。

然而,当我删除前 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.

我的想法是,在 Linux 上的 gcc 10.2.0 上,

  • 在第一种情况下,当使用 &x 时,x 是 存储在比 y 低的地址处,占 4 个字节。作为 int 在我的电脑上有 4 个字节,&x - &y 始终是 -1
  • 在第二种情况下,当不使用 &x 时,x 存储在比 y 高 4 个字节的地址处。

所以编译器确实设置了空间来存储 xy,即使没有使用 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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。