在用户可编程计算器中防止堆栈溢出/无限递归

时间:2011-01-25 00:06:25

标签: c recursion stack-overflow

我写了一个用户可编程的计算器,现在我遇到了以下问题。

假设用户在其中写下以下内容:

fun(n) = fun(n-1)

然后尝试调用fun(42)(或任何数字)。很明显,用户的代码会导致无限递归,从而导致整个计算器因堆栈溢出而崩溃。

如何让计算器优雅地退出计算?

我已经看过Mathematica如何处理类似的情况,它只是勉强说出

$IterationLimit::itlim: Iteration limit of 4096 exceeded.

我尝试过类似的方法,但是,由于堆栈大小与操作系统有关,我怎么知道使用哪个数字作为迭代限制(是的,我发现了一个通过实验“似乎工作”的数字,但那感觉不对??

感谢您的时间。计算器的核心是用C语言编写的。

3 个答案:

答案 0 :(得分:4)

这只是C中丑陋的小角落之一 - 没有可移植的方式来了解你可以安全使用多少堆栈。从技术上讲,甚至没有足够的堆栈来调用main()中的单个函数 - 它被认为是实施质量问题。

最安全的方法是展开您的递归,以便它使用您使用malloc()分配的自己的表达式堆栈,而不是无限制的真正递归。这样,如果malloc()在达到应用程序定义的递归限制之前返回NULL,则可以挽救。

答案 1 :(得分:2)

不是将用户级数学函数调用实现为C函数调用,而是使用malloc实现自己的基于堆的堆栈。这将为您提供更多级别的递归和一种可靠地判断失败的方法。

或者,您可以对递归级别设置一个相当小的限制。

答案 2 :(得分:0)

快速入侵就是跟踪递归深度,如果超出则退出。一个计数器就足够了。当然,您可能需要在每次评估之间重置计数器 - 但它不像运行自己的堆栈那样强大。