遞歸實驗-C語言遞歸調用的極限

轉自: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

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