You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何同一变量var的内存地址在两次运行中发生变化?

问题描述

我正在通过实验学习指针以加深理解,遇到了这样的情况:我声明了变量var和两个指针,在打印var的地址并与两个指针对比时,发现即使核心声明语句一致,var的地址却在两个值间变化。

第一次运行情况

代码:

#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

第二次运行情况

代码:

#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的地址每次运行都相同,请问为何会发生变化?


原因解析

1. 地址空间随机化(ASLR)的作用

现代主流操作系统(Windows、Linux、macOS等)默认开启**地址空间随机化(ASLR)**机制。该机制会在每次程序启动时,随机调整进程内存中栈、堆、动态链接库等区域的起始地址,以此防范缓冲区溢出等依赖固定内存地址的攻击手段。这直接导致同一程序每次运行时,局部变量所在的栈地址不会固定。

2. 栈帧布局的差异

两次运行的代码中,printf调用的数量不同,这会改变函数栈帧的结构。函数调用时,栈上会存放参数、返回地址、寄存器备份等数据,printf数量越多,栈上占用的临时空间就越多,编译器分配局部变量的位置会随之调整。第一次代码有5个printf,第二次只有3个,栈帧的大小和布局变化,最终导致var的地址出现差异。

此外,C语言标准并没有对局部变量的内存地址作出固定的规定,编译器和操作系统完全有权根据运行环境、代码结构调整变量的分配位置,所以你预期地址固定的想法并不符合实际的程序运行机制。


内容的提问来源于stack exchange,提问作者Bemin Dawoud

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 17:40:28