我写了一个用户可编程的计算器,现在我遇到了以下问题。
假设用户在其中写下以下内容:
fun(n) = fun(n-1)
然后尝试调用fun(42)
(或任何数字)。很明显,用户的代码会导致无限递归,从而导致整个计算器因堆栈溢出而崩溃。
如何让计算器优雅地退出计算?
我已经看过Mathematica如何处理类似的情况,它只是勉强说出
$IterationLimit::itlim: Iteration limit of 4096 exceeded.
我尝试过类似的方法,但是,由于堆栈大小与操作系统有关,我怎么知道使用哪个数字作为迭代限制(是的,我发现了一个通过实验“似乎工作”的数字,但那感觉不对??
感谢您的时间。计算器的核心是用C语言编写的。
答案 0 :(得分:4)
这只是C中丑陋的小角落之一 - 没有可移植的方式来了解你可以安全使用多少堆栈。从技术上讲,甚至没有足够的堆栈来调用main()
中的单个函数 - 它被认为是实施质量问题。
最安全的方法是展开您的递归,以便它使用您使用malloc()
分配的自己的表达式堆栈,而不是无限制的真正递归。这样,如果malloc()
在达到应用程序定义的递归限制之前返回NULL
,则可以挽救。
答案 1 :(得分:2)
不是将用户级数学函数调用实现为C函数调用,而是使用malloc实现自己的基于堆的堆栈。这将为您提供更多级别的递归和一种可靠地判断失败的方法。
或者,您可以对递归级别设置一个相当小的限制。
答案 2 :(得分:0)
快速入侵就是跟踪递归深度,如果超出则退出。一个计数器就足够了。当然,您可能需要在每次评估之间重置计数器 - 但它不像运行自己的堆栈那样强大。