轉自:http://sunxiunan.com/?p=1784
C語言遞歸調用不是無限的,當遞歸到一定時候,會出現stack over flow的問題。http://en.wikipedia.org/wiki/Stack_buffer_overflow
但是,這個度是多少呢?
我構造了一個極爲簡單的C語言遞歸程序,大家可以參考這裏https://gist.github.com/749543
#include "stdafx.h"
int count = 0;
void f()
{
int a = 1; int b = 1; int c = 1; int d = 1;
a = b + 3;
c = count + 4;
d = count + 5*c;
count++;
printf("count: %d\n", count);
f();
}
int _tmain(int argc, _TCHAR* argv[])
{
f(); return 0;
}
我使用的是VC2010SP1的C語言模式編譯,console程序,無優化。
運行結果如下:
默認情況下,count最後結果爲42860,然後程序就結束了。通過查詢MSDN可以知道
http://msdn.microsoft.com/en-us/library/8cxs58a6%28v=vs.80%29.aspx
我們可以通過修改project的link選項中的stack commit size和stack reserve size來改變程序的stack大小。
如果這兩個size都設置爲1、64、640、2048這幾個值,結果都是10092.
如果size設置爲1024000,那麼結果是42860,與默認情況相同。可以看出這個size是以BYTE爲單位。
如果size設置爲1048000,結果爲43372.
size設置爲1072000以及2048000,結果都是86551.
size設置爲2110000以及3072000,結果都是130242.
一般來說,我們基本上不需要考慮修改這個大小,因爲很少會有將近四萬的遞歸層次,默認值已經足夠用了。但是如果萬一不夠用或者有這種遞歸需求,那麼就需要修改這兩個值,另外當我們新建一個線程的時候,也可以編程修改線程stack的大小。
http://cs.nyu.edu/exact/core/doc/stackOverflow.txt 這裏解釋了一下不同平臺上stackoverflow的問題,有一些數據可以參考。
http://stackoverflow.com/questions/53827/checking-available-stack-size-in-c 在這裏有人提供了一個有趣的遞歸C代碼片段來判斷棧大小。
在這裏多廢話幾句,關於Lua的proper tail call http://www.lua.org/pil/6.3.html 。當我們使用Lua for windows構造一個簡單的遞歸程序運行,依然是會得到stack over flow的結果。但是當我們使用proper tail call這種方式調用,(由於拋棄了前面程序的棧)調用可以無限循環下去,所以Lua這個特性常常用來構造state machine。關於使用proper tail call來實現斐波拉契,可以參考這裏http://lua-users.org/wiki/ProperTailRecursion