質問

以下の C# コードがクラッシュしない理由を誰かが説明してもらえますか?Visual Studio で実際にコンパイルできるのはなぜですか?私の理解では、固定ポインターを取得していますが、それは「fixed」ステートメント内でのみ固定されています。ポインタが「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;
    }
}
役に立ちましたか?

解決

Eric の言うことは正しいですが、おそらくあなたが聞きたい答えは、「固定ステートメントの外側にアドレスを保持すると便利な場合がある」ということです。

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

そうは言っても、私は、コンパイラーが自分の足を切断することを許可しているここに、CodeAnalysis またはその他の高度なツールが介入することを望みます。

他のヒント

のメモリが解放されたからといって、それへの書き込みがどのような種類のエラーを引き起こすことを意味するものではありません。ガベージコレクタはメモリを再利用すると、それだけで、それが内部メモリマップですのように自由にマーク - 。それはすぐに戻ってOSにそれを与えていないので、それはまだあなたのプロセスが使用する有効なメモリです。

もちろん、それのための固定ブロックの外にポインタを使用すると、の非常にの悪い考えである - それをしない

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top