变量的范围和生命周期之间的关系是什么?如果变量超出范围,则其内存是否允许被另一个变量覆盖,或者在保留该函数之前保留该空间.
我很想,因为我想知道下面的代码是否真的有效,或者是否可能是*p未定义
foo() {
int *p;
{
int x = 5;
p = &x;
}
int y = *p;
}
Run Code Online (Sandbox Code Playgroud)
Alo*_*ave 28
什么是范围?
范围是可以访问变量的代码的区域或部分.
什么是一生?
生命周期是对象/变量处于有效状态的持续时间.
对于,自动/本地非静态变量Lifetime仅限于它们Scope.
换句话说,一旦创建它们的范围({,})结束,自动变量就会自动销毁.因此,名称自动开始.
您的代码示例有什么问题?
所以,您的代码具有未定义的行为.
在您的示例范围内,*p它是创建后的整个函数体.
但是,它x是一个非静态的本地/自动变量,因此一旦范围结束不存在x,它的范围就是结束的生命周期,即}创建它的结束括号x.*p指向不再存在的东西.
请注意,技术上x不存在超出其范围,但是可能发生编译器没有删除内容,x并且可能x通过指针访问超出其范围的内容(如您所做).但是,执行此操作的代码不是有效的C++代码.它是一个调用Undefined Behavior的代码.这意味着任何事情都可能发生(你甚至可能看到x完整的价值),并且不应该期望这样的代码可观察到的行为.
对于标识符指定的每个不同实体,标识符仅在称为其范围的程序文本的区域内可见(即,可以使用).由相同标识符指定的不同实体具有不同的范围,或者在不同的名称空间中
.
对象的生命周期是程序执行的一部分,在此期间保证为其保留存储.
在你的情况下x是块的本地,它的生命周期也是如此,因此x不能通过它在块外的名称访问,也因为它的生命周期限于它的块x,在离开块之后不再保留地址,因此将导致未定义的行为.
另一方面,例如,假设一个static局部变量,在这种情况下,范围是块的本地,因此我们不能通过其名称访问块外,但生命周期是整个程序,所以我们可以使用程序运行时任何位置的变量地址.这个例子应该有助于发挥作用.
对象(即存储值的实际底层事物)具有生命周期.
变量(即用于引用对象的东西)具有范围.
无论哪种方式,都会y = *p调用未定义的行为; 引用的对象x是自动的,它的生命周期在x超出范围时结束.