我運行在MATLAB遞歸函數,並得到該錯誤消息時超出堆棧空間:500達到遞歸
「最大遞歸限制使用set(0,‘RecursionLimit’,N) 改變極限。請注意,超出你的可用堆棧空間可能會使MATLAB和/或你的電腦崩潰。
我想知道,如果我改變遞歸限制並超過我的堆棧空間,是否真的會發生MATLAB和/或我的電腦崩潰?對我來說似乎很難。爲什麼MATLAB不會自動停止並在可用堆棧空間被超過時自動退出?
我如何知道我可以選擇沒有危險的遞歸極限?
我運行在MATLAB遞歸函數,並得到該錯誤消息時超出堆棧空間:500達到遞歸
「最大遞歸限制使用set(0,‘RecursionLimit’,N) 改變極限。請注意,超出你的可用堆棧空間可能會使MATLAB和/或你的電腦崩潰。
我想知道,如果我改變遞歸限制並超過我的堆棧空間,是否真的會發生MATLAB和/或我的電腦崩潰?對我來說似乎很難。爲什麼MATLAB不會自動停止並在可用堆棧空間被超過時自動退出?
我如何知道我可以選擇沒有危險的遞歸極限?
計算機不會崩潰。 Matlab可能會依賴於它們對堆棧的處理。最有可能的警告是因爲Matlab是多平臺的,它可以運行在許多不同的操作系統和體系結構上,其中一些可能不如Windows或大多數POSIX那樣安全。
實際上,在Windows機器上使用線程堆棧時,「堆棧溢出」錯誤實際上是「訪問衝突」 - 您嘗試訪問不屬於您的內存實際上並非訪問衝突(相反,它基本上是一種特殊類型的頁面錯誤),但這個想法是相似的 - 操作系統首先通知您,您已達到堆棧的上限,並且如果超過了最後幾個「安全」頁面,它會給你實際的堆棧溢出。這非常方便,因爲它是「免費」的 - 您不必檢查每次您是否還有堆棧空間push
,並且它爲您提供了一些額外的安全性。
取決於Matlab如何處理該異常,它可能優雅地報告錯誤並繼續,或者可能會崩潰。
當然,處理堆棧溢出可能非常棘手,但不適用於操作系統。 Windows可以很好地處理這些錯誤,它並不真正關心。
遞歸限制很大程度上取決於Matlab實際上在遞歸的每個步驟中必須存儲多少數據。 Windows線程的典型堆棧大小約爲256-1024kB(並且可以自行開始配置線程),這實際上相當多,除非你傳遞了很多大的論據。考慮到使用兩個整數並且沒有任何變量的方法,您甚至需要大約20 000次深度遞歸來超過256 kiB堆棧空間(在32位上)。
但是,堆棧溢出通常是代碼中的問題。你通常選擇錯誤的遞歸退出條件來遇到它們。這就是堆棧溢出由「異常」處理而不是爲堆棧分配更多內存的原因之一 - 每個微不足道的遞歸錯誤都會導致所有應用程序甚至操作系統崩潰。所以,首先確保你確實需要一個深度遞歸:)
你有一些細節錯誤,[這篇文章](http://stackoverflow.com/a/22467611/17034)可能有幫助。 –
@HansPassant謝謝你,現在它離家更近了嗎? – Luaan
其實here is a very similar question presented by Mathworks。
這裏是他們怎麼說你就可以生產遞歸問題,我覺得它有一點32位,所以你可能需要增加5000:
創建以下文件:
function retVal = myrecursivefun(inVal, recursions)
recursions = recursions - 1;
inVal = inVal + 1;
if recursions > 0
retVal = myrecursivefun(inVal, recursions);
else
retVal = inVal;
end
然後運行如下崩潰MATLAB:
set(0,'RecursionLimit', 5000);
myrecursivefun(1, 5000);
個人註釋:我覺得默認的重500的詛咒限制是有道理的。 Matlab程序員通常不會想要超越這個,大多數情況下這個限制是由於一個錯誤而造成的。
另外,我認爲matlab比C++等低級語言有更多的函數調用開銷,因此您通常首先要避免深度遞歸。
它肯定會退出。只是不以非常友好的方式。如果沒有足夠的堆棧空間,則沒有足夠的空間來顯示友好的消息。這個網站有一個很好的理由,堆棧溢出是*討厭*錯誤。 –
我不認爲有一個安全的方法來選擇限制,但如果您將可用空間的數量除以函數的一個實例使用的數量,您可以瞭解上限。 –