我在MATLAB中运行递归函数并收到此错误消息:
"达到最大递归限制500。使用set(0,' RecursionLimit',N) 改变限制。请注意,超出可用堆栈空间可以 崩溃MATLAB和/或您的计算机。"
我想知道,如果我更改递归限制并超出我的堆栈空间,那么MATLAB和/或我的计算机是否会崩溃?对我来说这似乎很刺激。如果超出可用的堆栈空间,为什么MATLAB不会自动停止并退出?
我怎么知道在没有危险的情况下我可以选择多大的递归限制?
答案 0 :(得分:1)
计算机不会崩溃。 Matlab可能,这取决于他们对堆栈的处理。警告很可能是因为Matlab是多平台的,它可以运行在许多不同的操作系统和体系结构上,其中一些可能不像Windows或大多数POSIX那样安全。
实际上,在Windows机器上使用线程堆栈时,“堆栈溢出”错误实际上是“访问冲突” - 您尝试访问不属于您的内存而不是实际上是一个访问冲突(相反,它是一种特殊的页面错误,基本上),但是这个想法是相似的 - 操作系统首先通知你你已达到堆栈的上限,如果你超过最后几个“安全”页面,它会给你实际的堆栈溢出。这非常方便,因为它是“免费的” - 你不必每次push
都检查是否仍有堆栈空间,它会给你一些额外的安全性。
根据Matlab处理该异常的方式,它可能会优雅地报告错误并继续,或者可能会崩溃。
当然,处理堆栈溢出可能非常棘手,但不适用于操作系统。 Windows可以很好地处理这些错误,它并不真正关心。
递归限制很大程度上取决于Matlab在递归的每个步骤中实际存储的数据量。 Windows线程的典型堆栈大小约为256-1024 kiB(并且它可以为您自己启动的线程配置),实际上相当多,除非您传递了很多大的参数。考虑到一个采用两个整数并且没有任何变量的方法,你需要大约20 000个调用深度递归才能超过256 kiB堆栈空间(在32位上)。
但是,堆栈溢出通常是代码中的问题。您经常通过选择错误的递归退出条件来遇到它们。这就是为什么堆栈溢出由“异常”处理的原因之一,而不是为堆栈分配更多内存 - 每一个简单的递归错误都会导致所有应用程序甚至操作系统崩溃。所以,首先要确保你真的需要一个深度递归:)
答案 1 :(得分:0)
实际上是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 ++这样的低级语言要多一些,因此你通常希望首先避免深度递归。