2013-04-20 46 views
5

爲了瞭解C++遞歸調用的限制,我嘗試了這個函數!限制C++中的遞歸調用(約5000)?

void recurse (int count) // Each call gets its own count 
{ 
printf("%d\n",count); 
    // It is not necessary to increment count since each function's 
    // variables are separate (so each count will be initialized one greater) 
    recurse (count + 1); 
} 

當count等於4716時,這個程序停止!所以限制只是4716! 我有點困惑!當計數等於4716時,爲什麼程序停止執行! PS:在Visual studio 2010下執行。 謝謝

回答

11

遞歸調用的限制取決於堆棧的大小。 C++語言並不限制這一點(從內存來看,符合標準的編譯器需要支持多少個函數調用的下限是一個相當小的值)。

是的,遞歸「無限」將停止在某個點或另一個點。我不完全確定你還期望什麼。

值得注意的是,設計軟件來做「無限」遞歸(或遞歸運行到數百或數千)是一個非常糟糕的主意。沒有(標準)方法來找出堆棧的限制,並且不能從堆棧溢出崩潰中恢復。

您還會發現,如果添加一個數組或其他某種數據結構[並使用它,所以它不會被優化],遞歸限制就會降低,因爲每個堆棧幀在疊加。

編輯:我其實會期望一個更高的限制,我懷疑你是在調試模式下編譯你的代碼。如果你在發佈模式下編譯它,我預計你會得到幾千更多,甚至可能是無限的,因爲編譯器會將你的尾遞歸轉換成循環。

+0

無邊界遞歸在某些目標上是可能的。 GCC支持所謂的「拆分堆棧」,它允許堆棧增長,*不連續地*填充可用內存。見http://gcc.gnu.org/wiki/SplitStacks – 2013-04-20 23:26:46

+0

我知道有一個限制,但我想知道這個限制是什麼!我沒想到這個堆棧會在少於5000個電話中爆炸!感謝您的解釋 ! – satyres 2013-04-20 23:27:52

+0

仍然有一個限制,並且仍然(據我所知)沒有辦法檢測到堆棧用完。使用軟件堆棧,至少有一種方法可以檢測堆棧何時耗盡...... – 2013-04-20 23:28:07

1

您可能已經用完了堆棧空間。

每次調用遞歸函數時,都需要在堆棧上推送一個返回地址,以便知道函數調用後返回的位置。

它在4716處崩潰,因爲它恰好在約4716次迭代後耗盡了堆棧空間。

+0

但它太小了!只有5000個電話!如何知道堆棧的最大尺寸! – satyres 2013-04-20 23:22:23

+0

我以爲堆棧大小與計算機的內存大小有關!所以我必須在VS2010中進行更改! – satyres 2013-04-20 23:24:55

+1

默認堆棧大小通常在可執行文件中設置。我不知道你是從哪裏得知與計算機有多少內存有關的想法。 – tangrs 2013-04-20 23:26:45

2

堆棧大小取決於您的環境。

例如,在* NIX中,您可以修改環境中的堆棧大小,然後運行您的程序,結果將會不同。

在Windows中,你可以改變這種方式(source)

$ editbin /STACK:reserve[,commit] program.exe 
+0

非常感謝這些信息! – satyres 2013-04-20 23:30:03