在函数外存取局部变量的一个比喻

标签: C/C++语言 C++ | 发表时间:2011-06-28 11:35 | 作者:陈皓 rex
出处:http://coolshell.cn

在StackOverflow上一这样一个关于C/C++的问题,问问题的人给了一个代码如下:

int * foo()
{
    int a = 5;
    return &a;
}

int main()
{
    int* p = foo();
    cout << *p;
    *p = 8;
    cout << *p;
}

你可以编译并运行这个代码(编译时会有一个Warning),结果是:5 8。看上去你可以存取一个函数内的局部变量。但这和我们理解的不一样——函数内的变量在函数退出时就被释放了,不应该在外部还可以被引用。当然,对于C/C++熟悉的人都知道其实并不是真正的释放,你依然还可以通过内存地址去进行操作,这是C/C++的内存管理的不安全性——指针可以用来乱指。

这个问题的解答是比较简单的,但是这个问题有一个答案中的比喻非常精彩。这个比喻是这样的——

你在某个酒店订了一个房,你入住的时候,你放了一本书在这个酒店的抽屉里,但是你走的时候,你忘了这本书。而且,你还没有把这个房间的钥匙还回去。于是,你在未来某个时候,偷偷地回来,打开这个房间的门,你看到了你的书还在里间。当然,还还可以放回别的书。因为,这个酒店管理不会在你走的时候把你留下的书清走,而且,这个酒店的管理的安保措施不是那么严格,因为他信任每一个客人都会遵守管理条例。

在这种情况下,如果你幸运的话,书还会在那里,也可能你的书已经没了。也有可能当你回去的时候,有一个人在那里正在撕你的书,或者酒店把那个抽屉都挪走并变成衣柜,或是整个酒店正在被拆除以改成了一个足球场,而你偷偷摸摸进到施工现场的时候被炸死。

真是很精彩的比喻。这就是C/C++的不安全的地方,也正是Linus说的,C++是一门恐怖的语言是因为有很多不合格的程序员在使用它。就像你看到小孩子玩火一样的恐怖。

关于这个事,还有一个比较经典的示例如下—— 函数a的初始化会影响函数b的数组。注意函数a中的 volatile 关键字。

#include <iostream>
using namespace std; 
void a()
{
    volatile int array[10];
    for (int i = 0; i < 10; i++)
        array[i] = i;
}

void b()
{
    int array[10];
    for (int i = 0; i < 10; i++)
        cout << array[i];
}

int main()
{
    a();
    b();
}

真是可爱的C/C++。

相关文章

相关 [函数 局部变量 比喻] 推荐:

在函数外存取局部变量的一个比喻

- rex - 酷壳 - CoolShell.cn
在StackOverflow上一这样一个关于C/C++的问题,问问题的人给了一个代码如下:. 你可以编译并运行这个代码(编译时会有一个Warning),结果是:5 8. 看上去你可以存取一个函数内的局部变量. 但这和我们理解的不一样——函数内的变量在函数退出时就被释放了,不应该在外部还可以被引用. 当然,对于C/C++熟悉的人都知道其实并不是真正的释放,你依然还可以通过内存地址去进行操作,这是C/C++的内存管理的不安全性——指针可以用来乱指.

世界上最有趣的比喻

- 阳阳 - 东西
读到其中一些搞笑的比喻时,我笑得眼泪都流出来了. 还有一年一度的英语教师奖,用来奖励在学生论文里发现最佳比喻和类比的教师. 各种想法在他脑海中翻滚打搅,就像一堆内裤在无防粘功能的烘干机中. 他以一副过来人的口气谈论着,就像一个不借助有针眼的纸筒观看日食而双目失明的人,奔走于全国的各所中学,告诫学生这样做的危害.

比喻的樂趣與力量(2011)

- votis - Taiwan 2.0
有效的比喻可以促進溝通,創造比喻的過程更能夠磨鍊思考. 2010 年八月的〈比喻的樂趣與力量(2010)〉彙整了那之前的一整年我在 Twitter 上使用過的有趣比喻.

剧情函数库

- SourBell - 学而时嘻之
(《新知客》,2010年10月). 著名物理学家徐一鸿先生在《可怕的对称》这本书中谈到对称性群的时候提到一个很有意思的笑话. 有一个客人随他的朋友参加一个笑话俱乐部的聚会. 另一个站起来叫道,“S—5”,引得所有的人都笑了起来. 这个迷惑不解的客人问道,这是怎么回事. 他的朋友解释道:“所有可能的笑话,当然不能计细小的差别,都已经被归类编上号了,我们心里都知道这些编号指的是什么.

函数图像(二)

- DreamToTrue - C++博客-λ-calculus(惊愕到手了欧耶)
    今天终于把雏形给做出来了. 主要的方法是牛顿迭代法,把屏幕上的所有点都收敛到函数图像上面. 为了提速,我是用了ThreadTool.QueueUserWorkItem和Parallel.For,还把那颗函数的语法树用Linq.Expression编译成了机器码. 下面的这些图都是二十秒钟左右就可以画出来的了.

Oracle函数介绍

- - CSDN博客数据库推荐文章
在SQL中有两种函数一种是单行函数,一种是多行函数.在sql与pl/sql中都自带了很多类型的函数,比如有字符、数字、日期、转换和混合型等多种函数用于处理单行数据,因此这些都被称为单行函数.这些函数都可以被用于select、where和oder by等子句中.下面我们就来分析单行函数,在这里我列举了oracle中一些常用的单行函数进行操作.希望你所有收获:.

MySql常用函数

- - CSDN博客数据库推荐文章
MySql函数众多,这里只是列举了一部分常用的函数. ABS(x)                                         // 返回x的绝对值. BIN(x)            //返回x的二进制(OCT返回八进制,HEX返回十六进制). CEILING(x)                                 //返回大于x的最小整数值.

转载 《关于时代的几个比喻》

- 研究研究 - caowumao的博客

Flipboard是一款电子杂志,这个比喻好不好?

- - 36氪
编者按:Flipboard可以说是社交阅读杂志的领头羊之一. 在iPad推出不久,这款应用就曾让乔布斯眼前一亮. 但是,Flipboard最初是怎么想到用“电子杂志”这一概念的呢. 在过去的Macworld亚洲博览会国际论坛上,Flipboard产品管理副总裁Gloria Lin向我们讲述了背后的逻辑:.

三角函数的笑话

- Michael - Dongde.in 您懂的!
15则三角函数的笑话,需要点儿智商才能看懂呀. 1、sin对cos说:虽然我们相爱了,但我总是感觉不对. sin说:我总觉得我们是在三角恋. 2、sin的爸爸问sin的妈妈:sin现在正交的女朋友是谁啊. sin的妈妈说:sin正交的应该是cos吧. 3、sin对cos说:我除了你,心中还有一个人.