局部变量保存相同的内存地址

时间:2017-11-04 10:14:48

标签: c++ variables memory-address

以下程序打印两个不同变量的地址。

#include <iostream>
using namespace std;

void f1()
{
    int i,k;
    cout<<"f1 : "<<&i<<endl;
}

void f2()
{
    int j;
    cout<<"f2 : "<<&j<<endl;
}

int main() {
    f1();
    f2();
    return 0;
}

Live demo

当我在GCC上运行这个程序时,我想知道,两个变量都有相同的地址。

为什么两个变量都保持地址相同?

编辑:

void f1()
{
    int i = 10;
    cout<<"f1 : "<<&i<<endl;
    cout<<"value of  : "<<i<<endl;
}

void f2()
{
    int j;
    cout<<"f2 : "<<&j<<endl;
    cout<<"value of j : "<<j<<endl;
}

int main() {
    f1();
    f2();
    return 0;
}

Live Demo 2

在此示例中,如果我将值 10 分配给i,则j也会打印10。我认为这是无效的,因为j未初始化。

6 个答案:

答案 0 :(得分:13)

因为它们的生命周期不重叠,所以编译器能够重用它们的存储。

答案 1 :(得分:3)

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

堆栈空间用于保存调用函数时从函数返回所需的信息及其局部变量。当函数返回时,从堆栈中删除局部变量,并从堆栈中删除返回信息,使堆栈返回调用函数时的位置。由于两个函数调用是相似的,因此它们在两种情况下都与堆栈相同,使得局部变量具有相同的地址。

答案 2 :(得分:2)

他们正在使用相同的堆栈内存块。返回f1调用后,堆栈内存空闲。然后f2再次获得相同的堆栈内存。所以,如果你在另一个函数f3中调用f2,那么你可能会看到不同的地址。

答案 3 :(得分:2)

  

在该示例中,如果我将值10分配给i,则j也会打印10   认为这是无效的。

在此示例中,您没有使用c ++的任何内存分配概念。因此,您刚存储在fun2中的值将保留,因为它从未从为i分配的内存中删除,然后当您调用j时,为<script> var $input = $('#player_list'); $input.select2({ placeholder: "Player...", minimumInputLength: 2, ajax: { url: '/{{ $region }}/search', dataType: 'json', data: function (params) { return { q: $.trim(params.term) }; }, processResults: function (data) { return { results: data }; }, cache: true } }); $input.on('select2:selecting', function(e){ window.location = e.params.data.url; }); </script> 分配了相同的内存。这就是为什么你为这两个变量和同一地址得到相同的值。

答案 4 :(得分:1)

  

在该示例中,如果我将值10分配给i,则j也会打印10.我认为它无效。

关于你的第二个例子(请在问题中发布与问题相关的代码,不要链接&#39; em)

void f2()
{
    int j;
    cout<<"f2 : "<<&j<<endl;
    cout<<"value of j : "<<j<<endl;
}

这是未定义的行为j具有不确定的值,任何(*)评估导致不确定的值(在cout<<j调用时出现的值)给出了未定义的行为

实际上,这包括拥有一个任意值,陷阱表示(在拥有它们的平台上,据我所知,现在肯定不是很多:))并且最糟糕地允许编译器进行优化,好像j具有字面上的任何值(导致可能)逻辑违抗行为)。

(*)有例外,但在这种情况下不相关

答案 5 :(得分:0)

你应该知道变量在本地的不同函数中局部变量和全局变量的工作情况。

每次调用该函数时,它都会为其分配值和内存地址,因为它存储在堆栈内存中并通过函数结束进行清理。内存被释放,同样的内存可以再次使用。

但可能是你的编译器生气了。 输入完整的源代码然后仔细弄清楚。