【问题标题】:Why is the address of a local variable identical for different executions?为什么局部变量的地址对于不同的执行是相同的?
【发布时间】:2013-02-08 07:51:21
【问题描述】:
int fun(int x);

int main()
{
    fun(10);
    fun(11);   
    return 0;
}

int fun(int x)
{
    int loc;//local variable
    cout<<&loc;
    return 0;
}

输出是

0xbfb8e610 
0xbfb8e610

这里的 loc 是一个局部变量,它在第一次执行函数 f(10) 后超出范围,然后再次分配给下一次执行 fun(11)。因此,根据我的理解,loc 变量的地址必须不同。那为什么两个执行的地址&amp;loc是一样的呢?

【问题讨论】:

  • “所以地址必须不同。”是什么让你这么认为?
  • 因为它们被一个接一个地调用,所以它们可以使用堆栈上的相同空间。
  • 嗯,还有什么变量? :) 对fun 的两次调用之间没有任何内容。如果您从堆栈中取出某个东西,然后立即将其放回原处,它会在同一个地方。
  • @SubiSuresh 内存位置是虚拟的。 '你认为你现在呼吸的是空气吗?'
  • @SubiSuresh:同一内存不能被另一个进程使用,因为操作系统不允许。另一个进程可以使用相同的地址,但它会访问完全不同的内存。操作系统可以为进程创建任意数量的不同或部分重叠的内存空间,并且可以根据需要将这些空间的位和部分映射到物理内存的页面中。如果你真的想吃红色药丸,请阅读fork 是如何使用写时复制实现的。

标签: c++


【解决方案1】:

fun 的每次调用都需要自己的位置来存储变量。但是一旦函数返回,变量就不再存在。没有理由不能重复使用该地址。不一定是,但没有理由不能。

在典型的实现中,堆栈空间用于保存调用函数时从函数返回所需的信息及其局部变量。当函数返回时,局部变量从堆栈中删除,返回信息从堆栈中弹出,使堆栈回到调用函数时的位置。由于这两个函数调用是相同的,因此它们在两种情况下都以相同的堆栈结束,从而使局部变量具有相同的地址。这是一个有经验的程序员所期望的,但不是依赖的。

【讨论】:

    【解决方案2】:

    对堆栈中正在发生的事情进行了有点超简单(模糊)的说明。

    main()(假设0xtopomain 保持不变):

       ~Stack~
    ==============
    = 0xtopomain =
    = 0x........ =
    ==============
    

    首次执行fun()(推送):

       ~Stack~
    ==============
    = 0xothers.. =
    = 0xbfb8e610 = <- loc
    = 0xmemoffun = <- other memory allocated for fun()
    = 0xtopomain =
    = 0x........ =
    ==============
    

    返回main()(弹出):

       ~Stack~
    ==============
    = 0xtopomain = <- Where the hell is loc?!!
    = 0x........ =
    ==============
    

    第二次执行fun()(再次推送):

       ~Stack~
    ==============
    = 0xothers.. =
    = 0xbfb8e610 = <- loc's here again
    = 0xmemoffun = <- other memory allocated for fun()
    = 0xtopomain =
    = 0x........ =
    ==============
    

    【讨论】:

    • >非常感谢您的图片
    【解决方案3】:

    存储在堆栈中的局部变量(一个特殊的内存区域,新推送的变量位于顶部,旧变量位于底部)。当您调用函数时,会完成一些操作,例如存储返回地址、参数和寄存器等。但是有一个顺序。在返回时,所有推送的变量都从堆栈中弹出。由于您使用的是相同的函数并且在两次调用之间,您不会在主函数中使用任何局部变量,因此您的变量地址应该是相同的。

    【讨论】:

      猜你喜欢
      • 2015-10-25
      • 1970-01-01
      • 1970-01-01
      • 2022-11-23
      • 2021-11-12
      • 1970-01-01
      • 2016-05-08
      • 2021-04-01
      • 1970-01-01
      相关资源
      最近更新 更多