我用下面的代码完成了一个非常简单的programming excersize:
using System;
namespace Factorial
{
class MainClass
{
static int fives(int x) {
int r = 0;
while(x % 5 == 0) {
r++;
x /= 5;
}
return r;
}
static int z(int x) {
if (x == 1)
return 0;
else
return z (x-1) + fives (x);
}
public static void Main (string[] args)
{
int testCases = Convert.ToInt32 (Console.ReadLine ());
int[] xs = new int[testCases];
for (int i=0; i<testCases; i++)
xs [i] = Convert.ToInt32 (Console.ReadLine ());
foreach (int x in xs)
Console.WriteLine (z (x));
}
}
}对于小数字,它似乎工作得很好,但对于示例中的8735373,它会打印“分割错误: 11”。这是不是意味着我会因为递归太深入而耗尽内存?是什么原因?
(我在苹果电脑上运行Mono2.10.8版本的C#。)
附注:如果任何人对excersize本身感兴趣,可以使用here's my final solution (更优化)。
发布于 2012-05-30 06:00:05
如果问题是由大量递归引起的,则错误可能是StackOverflowException。正如前面所说的,我非常确定这是一个单声道故障。当试图到达不应该到达的内存地址而导致内存管理不善时,就会出现分段故障。这种类型的错误是系统错误...不是C#异常。我几乎可以肯定,Mono没有很好地管理大数字的内存。我希望这对你的研究有所帮助。
发布于 2012-05-30 05:48:26
这看起来像一个未处理的StackOverflowException -在过度使用递归时很常见。所以..。不要过度使用递归。它可能适用于数学和一些非常特定的语言(F#可能会应付),但C#...不是很多。
这看起来像(未经验证):
static int z(int x)
{
int accumulator = 0;
while(x!=1)
{
accumulator += fives(x);
x--;
}
return accumulator;
}它不会出错--它不会递归(尽管它每次迭代都会调用fives )。更好的方法是:做代数运算,找出直接公式。
发布于 2012-05-30 05:55:41
当您使用较大的递归步骤时,您的递归步骤会导致StackOverflowException,如果您查看调试器,就会发现在执行了多少个递归步骤之后就发生了异常。
我认为Mono代码以某种方式将堆栈溢出异常考虑到了Segmentaiton错误,这可能是它的处理方式。

如果愿意,您可以对其进行调试:How do I debug a segmentation fault in Mono on Ubuntu without any debugger?
https://stackoverflow.com/questions/10807059
复制相似问题