为了账号安全,请及时绑定邮箱和手机立即绑定

可以在其范围之外访问局部变量的内存吗?

可以在其范围之外访问局部变量的内存吗?

犯罪嫌疑人X 2019-05-20 16:04:46
我有以下代码。#include <iostream>int * foo(){     int a = 5;     return &a;}int main(){     int* p = foo();     std::cout << *p;     *p = 8;     std::cout << *p;}而代码只是运行而没有运行时异常!输出是 58怎么会这样?本地变量的内存不能在其功能之外无法访问吗?
查看完整描述

6 回答

?
翻阅古今

TA贡献1780条经验 获得超5个赞

你在这里做的只是读取和写入曾经是地址的内存a。既然你在外面foo,它只是指向一些随机存储区的指针。事实上,在您的示例中,该内存区域确实存在,此刻没有其他任何内容正在使用它。你不会因为继续使用它而破坏任何东西,而其他任何东西都没有覆盖它。因此,5仍然存在。在一个真实的程序中,该内存几乎可以立即重用,你可以通过这样做来破坏某些东西(尽管这些症状可能要到很晚才出现!)

当您返回时foo,您告诉操作系统您不再使用该内存,并且可以将其重新分配给其他内容。如果你很幸运,它永远不会被重新分配,并且操作系统不会让你再次使用它,那么你就可以逃脱谎言。尽管如此,你最终还是会写完最后的那个地址。

现在,如果你想知道编译器为什么不抱怨,那可能是因为foo优化消除了。它通常会警告你这类事情。C假设你知道你正在做什么,从技术上来说你没有违反范围(除了a它之外没有引用foo),只有内存访问规则,它只触发警告而不是错误。

简而言之:这通常不会起作用,但有时会偶然发生。


查看完整回答
反对 回复 2019-05-20
?
九州编程

TA贡献1785条经验 获得超4个赞

因为存储空间还没有被踩到。不要指望那种行为。


查看完整回答
反对 回复 2019-05-20
?
至尊宝的传说

TA贡献1789条经验 获得超10个赞

所有答案的一点点补充:

如果你做那样的事情:

#include<stdio.h>#include <stdlib.h>int * foo(){
    int a = 5;
    return &a;}void boo(){
    int a = 7;}int main(){
    int * p = foo();
    boo();
    printf("%d\n",*p);}

输出可能是:7

这是因为从foo()返回后,堆栈被释放,然后由boo()重用。如果您拆卸可执行文件,您将清楚地看到它。


查看完整回答
反对 回复 2019-05-20
?
Qyouu

TA贡献1786条经验 获得超11个赞

在C ++中,您可以访问任何地址,但这并不意味着您应该访问。您访问的地址不再有效。它的工作原理是因为在foo返回后没有其他东西扰乱内存,但在许多情况下它可能会崩溃。尝试用Valgrind分析你的程序,或者甚至只是编译它优化,看看......


查看完整回答
反对 回复 2019-05-20
  • 6 回答
  • 0 关注
  • 749 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信