固定ステートメント外の固定ポインタの動作が不明瞭
-
21-08-2019 - |
質問
以下の 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にそれを与えていないので、それはまだあなたのプロセスが使用する有効なメモリです。
もちろん、それのための固定ブロックの外にポインタを使用すると、の非常にの悪い考えである - それをしない
。所属していません StackOverflow