我的一个学生询问了C ++中局部变量的生命周期。我告诉他,它仅限于使用它的功能的主体,但是在我看到以下内容后我感到惊讶。
它声明了两个函数fun()
和fun2()
,并在两个函数中声明int i
。根据我的概念,int i
和fun()
的{{1}}将被保存为内存中的不同变量,但这两个函数都给我相同的内存地址。需要帮助。
fun2()
答案 0 :(得分:7)
我的一个学生问了一个问题,即c ++中局部变量的生命是什么。我告诉他,它仅限于使用它的功能的主体
这是不准确的。自动变量的生命周期一直延伸到声明变量的作用域的末尾。例如,复合语句中的变量(也称为块)会延伸到该复合语句的末尾,无论该复合语句是函数体还是嵌套在函数体中。
示例:
void foo() {
{
int i;
}
// lifetime of i has ended, but function hasn't returned yet
}
每个范围对于它们的延伸范围都有不同的规则。例如,函数参数的范围一直延伸到函数结束。在控制结构的子语句中声明的名称范围(如循环或条件语句)延伸到控制结构的末尾。
静态局部变量具有静态存储持续时间,其生命周期不受其声明范围的约束。
我声明了两个函数fun()和fun2()并在两个函数中声明了int i。根据我的概念,fun()和fun2()的int i将被保存为内存中的不同变量,但这两个函数都给我相同的内存位置
它们“保存为不同的变量”,但无论变量是否存储在单独的内存位置,都无关紧要。
实际上,根据您的概念,fun
的局部变量的生命周期已经结束,因此没有理由为fun2
的局部变量无法使用相同的内存 - 现在被破坏 - 过去的对象。
答案 1 :(得分:5)
根据我的概念,
i
和fun()
的intfun2()
将被保存为内存中的不同变量。
fun::i
和fun2::i
确实是两个不同的变量,具有不同的scope和storage duration。编译器选择将它们放在同一虚拟内存地址的事实不会改变任何内容。
但是这两个函数都给了我相同的内存位置。
之所以能够这样做,是因为在fun2()
返回后,它使用的堆栈空间(int fun2::i
)可用,fun::i
可以重用该空间。
总结一下,请参阅this answer from SO:
What is Scope?
范围是变量可以是代码的区域或部分 访问。
What is a lifetime?
生命周期是对象/变量处于有效状态的持续时间 状态。
对于,自动/本地非静态变量生命周期仅限于他们的 范围。换句话说,自动变量会自动销毁 一旦创建它们的范围(
{
,}
)结束。由此得名 自动开始。
答案 2 :(得分:3)
fun2
结束后,fun2
中的内存地址可以重复使用。
该内存位置恰好在fun
中重复使用
(不保证它将是相同的地址或不同的地址;两者都可以)
您是否认为可以保证永远不会在任何地方重复使用内存地址?您的计算机不会以这种方式耗尽内存吗?
如果您想查看使用的单独地址,请fun2
拨打fun
:
void fun2()
{
int i;
cout<<"This is the address in fun2:" << &i <<endl;
fun(); // This will show a different address.
}