6

次のコードを検討してください。

    private static int i = 0;

    static void Main(string[] args)
    {
        DoSomething();
        Console.ReadLine();
    }

    public static void DoSomething()
    {
        Console.WriteLine(i);
        ++i;
        DoSomething();
    }

実行するたびに、変数StackOverflowExceptionの値が異なりiます。たとえば、160231620016071

この背後にある理由は何ですか? C# コンパイラのバグですか?

4

2 に答える 2

4

無制限の再帰の動作は実装定義です。定義済みの実装とは、何でもできることを意味します。プログラムはいつでも終了する (または決して終了しない) か、未処理の例外をスローするか、その他何でも可能です。たとえば、MSIL としてコンパイルして 64 ビット OS で実行すると、プログラムが終了することはありません。これは、ジッターが再帰をループに変えることが許可されているためです。これは 64 ビット ジッターが行います。なぜ特定の値で終了するのかを尋ねても、ランタイムは何でもできるので、実用的な目的にはなりませ

于 2013-06-15T08:19:28.343 に答える
1

スタックサイズが十分ではありません。

新しいスレッドを開始し、コンストラクターで新しいスタックサイズを定義することで、デフォルトのスタックサイズを増やすことができます。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace ConsoleApplication3
{
class Program
{
    private static int i = 0;

    static void Main(string[] args)
    {
        Thread T = new Thread(DoSomething, 100000000);
        T.Start();
        Console.ReadLine();



    }

    public static void DoSomething()
    {
        Console.WriteLine(i);
        ++i;
        DoSomething();
    }

 }
}

Stackoverflow は、150 万回の再帰呼び出しで発生するようになりました。

于 2013-06-15T08:00:26.373 に答える