[轉]在函數外存取局部變量的一個比喻

原文出處:http://coolshell.cn/articles/4907.html

在函數外存取局部變量的一個比喻  作者:2011年6月28日 陳皓


在StackOverflow上一這樣一個關於C/C++的問題,問問題的人給了一個代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
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 關鍵字。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#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++。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章