从Scope vs. Lifetime of Variable我们看到来自Alok的anser部分:
请注意,技术上x不存在超出其范围的范围 可能会发生编译器没有删除x和的内容 一个人可能能够通过a访问超出其范围的x的内容 指针(就像你一样)。但是,执行此操作的代码不是有效的C ++ 码。它是一个调用Undefined Behavior的代码。意思是 任何事情都可能发生(你甚至可能看到x的价值完好无损)和 人们不应该期望这样的代码可以观察到行为。
这很有趣。为什么在变量x
达到}
后删除它?
答案 0 :(得分:4)
与删除硬盘上的文件时的概念相同,为什么只删除索引条目而不是格式化文件?
这需要时间。
答案 1 :(得分:2)
为什么不在变量x到达时删除变量x?
你是什么意思" 删除变量x
?"
唯一接近"删除"变量会在&x
覆盖它的值。编译器没有理由这样做,因为这会浪费时间。相反,当变量到达其范围的末尾时,代码就不能再通过它的名称访问x
(因此它的内存地址不再对其有效)程序员)并且内存地址再次可供系统使用。然后,当在某一点创建一些其他变量并且需要该地址空间时,该变量的值只写入&x
,覆盖它之前的值。
这也是为什么它的未定义行为读取单位资本化变量的原因,像int x;
这样的变量声明只保留一些空间,地址仍保留前面的值并需要被覆盖程序员明确地(int x = 0;
)。
答案 2 :(得分:0)
当一个变量超出范围时,允许编译器假设没有代码会尝试访问它 - 因为任何尝试这样做都会给出未定义的行为。
由于允许编译器假设没有代码访问不存在的变量,因此它可以在该变量不再存在后使用该变量占用的内存执行它喜欢的操作。它可以选择回收内存。它可以简单地保留内存,并在需要时重新分配它以供其他用途。如果愿意,它可以加密内存的内容。
实际上,编译器不会回收内存的原因是性能 - 在回收内存,清理内存以允许其他代码重用等方面存在性能损失。而且,因为编译器不是必需的要做任何这些事情,很少有编译器供应商会刻意做一些不必要的性能影响。