【问题标题】:Why the memory address contained in a pointer and the address of a pointer coming out same?为什么指针中包含的内存地址和指针的地址相同?
【发布时间】:2016-02-08 11:39:33
【问题描述】:

指针变量只是指向内存中的其他变量地址。而指针变量显然在内存中有自己的地址。

但是,此代码为两者提供了相同的内存地址。

int num=10;
int *ptr=#
printf("Address of variable num: %p\n",ptr);
printf("Address of pointer ptr: %d\n",&ptr);

如果同时打印它们,那么它似乎可以按预期工作。

变量num的地址:0028FF3C

指针ptr地址:0028FF38


但如果我一次打印它们,那么它会为两者提供相同的地址。

printf("Address of variable num: %p\n",ptr);
//printf("Address of pointer ptr: %d\n",&ptr);

变量num的地址:0028FF38

//printf("Address of variable num: %p\n",ptr);
printf("Address of pointer ptr: %d\n",&ptr);

指针ptr地址:0028FF38


我在 windows 7 机器上使用 mingw 编译器。

【问题讨论】:

  • 编译器优化在起作用?
  • 这可能是因为编译器看到您没有使用该变量并对其进行优化。您可以通过查看生成的汇编代码(gcc -S)来检查
  • 有点迂腐:“指针变量只指向内存中的其他对象”更准确。指针指向的对象不需要有任何变量。

标签: c pointers


【解决方案1】:

编译器只需要保证一个变量只要被使用就一直存在。

int a = 5;
int b = 7;
printf( "a * 5 = %d\n", a * 5); /* after this point, a is no longer needed */
printf( "b * 9 = %d\n", b * 9); /* after this point, b is no longer needed */

因此编译器可以将 b 初始化推迟到 a 完成之后,并且只使用一个内存位置。

同样在本例中,它可能会将常量 2​​5 和 63 压入堆栈,并且不会为 a 或 b 创建任何存储空间。

【讨论】:

  • 那么,这是因为编译器优化了代码以使其高效吗?
【解决方案2】:

它们是分配在堆栈中的局部变量。所以他们有连续的地址分配。

编译器通常会删除任何未使用的变量,因此注释掉 printf 可能会导致变量不存在。当一个不存在时,只有第一个被放入堆栈。 只要堆栈从同一位置开始并且具有相同的调用堆栈和局部变量,它们的地址将相同。

如果您不知道堆栈是什么,您可能想看看这个问题的答案。 What and where are the stack and heap?

【讨论】:

  • 为了让您的答案完全可以理解,您可能还需要解释为什么“一个不存在”,因为两者都在代码中声明,这只是被注释掉的 printf 语句(和编译器优化删除未使用的变量)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-03
相关资源
最近更新 更多