0

以下の C# コードがクラッシュしない理由を誰か説明してもらえますか? Visual Studio で実際にコンパイルできるのはなぜですか? 私の理解では、固定ポインターを取得していますが、「固定」ステートメント内でのみ固定されています。「Foo」関数からポインタが返されると、配列「ar」が収集される場合があります。次に、GC に実際にこれを実行させますが、メモリ (現在は割り当て解除されています) に連続して書き込みを行ってもエラーは発生しません。

class Program
{
    static unsafe byte* Foo()
    {
        byte[] ar = new byte[100];
        fixed (byte* ptr = ar)
        {
            return ptr;
        }
    }

    static unsafe void Main(string[] args)
    {
        byte* ptr = Foo();
        GC.Collect();
        for (int t = 0;;++t) ptr[t%100] = 0;
    }
}
4

2 に答える 2

1

エリックの言うとおりですが、おそらく聞きたい答えは、「定型文の外にアドレスを保持しておくと便利な場合がある」ということです。

おそらく、そのポインターからのメモリは、別の固定ステートメントによって別の場所で既に固定されており、それを返すことは理にかなっていますか? コンパイラは、あなたを推測してうるさい警告を出そうとはしていません。

とは言うものの、CodeAnalysis やその他の高度なツールが、コンパイラが自分の足を切断させているところに介入してくれることを願っています。

于 2009-05-14T18:53:23.107 に答える
1

メモリが解放されたからといって、メモリへの書き込みによって何らかのエラーが発生するわけではありません。ガベージ コレクターがメモリを再利用すると、その内部メモリ マップで空きメモリとしてマークされるだけです。すぐに OS に戻されるわけではないため、プロセスが使用できる有効なメモリのままです。

もちろん、固定ブロックの外でポインターを使用するのは非常に悪い考えです。使用しないでください。

于 2009-05-14T12:12:14.863 に答える