递归

2014-03-28 103 views
1

我运行在MATLAB递归函数,并得到该错误消息时超出堆栈空间:500达到递归

“最大递归限制使用set(0,‘RecursionLimit’,N) 改变极限。请注意,超出你的可用堆栈空间可能会使MATLAB和/或你的电脑崩溃。

我想知道,如果我改变递归限制并超过我的堆栈空间,是否真的会发生MATLAB和/或我的电脑崩溃?对我来说似乎很难。为什么MATLAB不会自动停止并在可用堆栈空间被超过时自动退出?

我如何知道我可以选择没有危险的递归极限?

+0

它肯定会退出。只是不以非常友好的方式。如果没有足够的堆栈空间,则没有足够的空间来显示友好的消息。这个网站有一个很好的理由,堆栈溢出是*讨厌*错误。 –

+0

我不认为有一个安全的方法来选择限制,但如果您将可用空间的数量除以函数的一个实例使用的数量,您可以了解上限。 –

回答

1

计算机不会崩溃。 Matlab可能会依赖于它们对堆栈的处理。最有可能的警告是因为Matlab是多平台的,它可以运行在许多不同的操作系统和体系结构上,其中一些可能不如Windows或大多数POSIX那样安全。

实际上,在Windows机器上使用线程堆栈时,“堆栈溢出”错误实际上是“访问冲突” - 您尝试访问不属于您的内存实际上并非访问冲突(相反,它基本上是一种特殊类型的页面错误),但这个想法是相似的 - 操作系统首先通知您,您已达到堆栈的上限,并且如果超过了最后几个“安全”页面,它会给你实际的堆栈溢出。这非常方便,因为它是“免费”的 - 您不必检查每次您是否还有堆栈空间push,并且它为您提供了一些额外的安全性。

取决于Matlab如何处理该异常,它可能优雅地报告错误并继续,或者可能会崩溃。

当然,处理堆栈溢出可能非常棘手,但不适用于操作系统。 Windows可以很好地处理这些错误,它并不真正关心。

递归限制很大程度上取决于Matlab实际上在递归的每个步骤中必须存储多少数据。 Windows线程的典型堆栈大小约为256-1024kB(并且可以自行开始配置线程),这实际上相当多,除非你传递了很多大的论据。考虑到使用两个整数并且没有任何变量的方法,您甚至需要大约20 000次深度递归来超过256 kiB堆栈空间(在32位上)。

但是,堆栈溢出通常是代码中的问题。你通常选择错误的递归退出条件来遇到它们。这就是堆栈溢出由“异常”处理而不是为堆栈分配更多内存的原因之一 - 每个微不足道的递归错误都会导致所有应用程序甚至操作系统崩溃。所以,首先确保你确实需要一个深度递归:)

+0

你有一些细节错误,[这篇文章](http://stackoverflow.com/a/22467611/17034)可能有帮助。 –

+0

@HansPassant谢谢你,现在它离家更近了吗? – Luaan

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++等低级语言有更多的函数调用开销,因此您通常首先要避免深度递归。