这里变量的地址为什么变了?

问题描述 投票:0回答:1

我正在尝试使用指针来更好地掌握它,我在这里遇到了这种情况: 我声明了一个变量 var 和两个指针。我正在打印 var 的地址以将其与两个指针进行比较,但即使语句相同,它仍然在两个值之间变化?

这是第一次将 var 的地址指定为

0061FF1C
:

我使用的代码:

#include <stdio.h>
 
int main () {

   int  var;
   int  *ptr;
   int  **pptr;

   var = 3000;
   ptr = &var;
   pptr = &ptr;

   printf("Address of var = %p\n", &var );
   printf("Value available at ptr = %p\n", ptr ); // should be equal to address of Var
   printf("Address of ptr = %p\n", &ptr ); // should be equal to address of ptr
   printf("value available at pptr = %p\n", pptr); // should be equal to address of ptr
   printf("address of pptr = %p\n", &pptr ); // should be equal to address of pptr
   return 0;
}

输出:

Address of var = 0061FF1C
Value available at ptr = 0061FF1C
Address of ptr = 0061FF18
value available at pptr = 0061FF18
address of pptr = 0061FF14

这是第二次将 var 的地址指定为

0061FF18
: 我使用的代码:

#include <stdio.h>
 
int main () {

   int  var;
   int  *ptr;
   int  **pptr;

   var = 3000;
   ptr = &var;
   pptr = &ptr;

   printf("Address of var = %p\n", &var );
   printf("Value available at ptr = %p\n", ptr ); // should be equal to address of Var
   printf("value available at pptr = %p\n", pptr); // should be equal to address of ptr

   return 0;
}

输出:

Address of var = 0061FF18
Value available at ptr = 0061FF18
value available at pptr = 0061FF14

我期望 var 的值每次都相同 为什么变了?

c pointers memory-address
1个回答
0
投票

在不打印

&pptr
的程序中,该对象不需要有地址,因此编译器可以通过不实际将其存储在内存中来优化程序。程序可以将
pptr
的值保存在处理器寄存器中和/或根据需要“动态”创建它。由于没有为其分配内存,这会改变其他对象(如
var
)的位置。

编译器可能会使用复杂的算法来为对象分配内存。然而,在这个有限的问题上,我们可以考虑一个简单化的观点。本质上,编译器准备需要存储在堆栈上的对象的信息,然后为这些对象在

main
的堆栈帧中分配位置,结果是它分配位置的第一个对象将最终位于地址 0061FF14 16,下一个在 0061FF1816,下一个在 0061FF1C16。 (堆栈帧中还有其他内容,这就是为什么我们在本例中看到的第一个对象从 0061FF1416 开始,而不是 0061FF1016 开始。)

在程序的第一个版本中,程序打印

var
ptr
pptr
的地址。所以这些对象必须有地址。无论出于何种原因,编译器都会按照
pptr
ptr
var
的顺序处理它们,分别为它们提供地址 0061FF1416、0061FF1816 和 0061FF1C16

在程序的第二个版本中,程序打印

var
ptr
的地址(后者通过将
&ptr
分配给
pptr
然后打印
pptr
)。它从不使用
pptr
的地址,因此
pptr
不需要有实际地址;编译器无需将
pptr
放入内存即可使程序运行。因此,对于这个程序,编译器为
var
ptr
分配内存,它们最终位于地址 0061FF1416 和 0061FF1816。因此
ptr
的地址与程序的第一个版本相差四个字节。

© www.soinside.com 2019 - 2024. All rights reserved.