0

私はCとポインタの使用に慣れています。C#でポインターを使用して多くのことを実行できることは知っていますが、ガベージコレクションは煩わしくなります。オブジェクトへのポインターを作成し、ポインターが生きている限りオブジェクトがクリーンアップされないように、ポインターをオブジェクトにリンクすることは可能ですか?何か嘘がある

unsafe void* Function1 () {
 SomeStruct s = new SomeStruct();
 void* ptr = (void*) &s;
 return ptr;
}

main() {
  void* p = Function1();
  p->field = 3;
}

これを実行しようとすると、オブジェクトは正常で、ポインターはFunction1内で機能しましたが、関数が終了するとすぐに、ポインターは有効でしたが、オブジェクトは破棄されました。ガベージコレクターに関する限り、2つをリンクする方法があれば素晴らしいでしょう。

4

3 に答える 3

2

SomeStruct型の名前がそれほど悪くなく、実際には aであると仮定するとstruct、スタックにメモリを割り当てています。

メソッドから戻ると、構造体が割り当てられているスタック フレームが削除されるため、メソッドの外では構造体は単に存在しなくなります。それを削除するのはガベージコレクターではないため、ガベージコレクターがそれを削除しないようにするためにできることは何もありません。それを行うメソッドから返されます。

structC# の a は C の a とは異なる概念であることに注意してくださいstruct。C# では構造体は常に値型ですが、C では使用方法に応じて値型または参照型のいずれかになります。

値を保持したい場合は、ボックス化してヒープに保持できます。ガベージコレクターはポインターを気にせず、参照のみを気にするため、ポインターではなく、ボックス化された値への参照を返します。

object Function1 () {
  SomeStruct s = new SomeStruct();
  // box the value:
  object o = s;
  return o;
}

main() {
  object p = Function1();
  // unbox the value:
  SomeStruct s = ((SomeStruct)p);
  s.field = 3;
}

もちろん、構造体をヒープに置く代わりに渡すことができます。

SomeStruct Function1 () {
  return new SomeStruct();
}

main() {
  SomeStruct p = Function1();
  p.field = 3;
}

本当に をstructヒープに格納する必要がある場合は、代わりに を作成することを検討する必要があります。そうすればclass、自動的にヒープに配置されます。

于 2012-10-26T21:23:51.570 に答える
1

SomeStruct実際structには値型であり、特定のケースではスタックに割り当てられていると仮定します。structC とstructC# では意味が異なることに注意してください。

于 2012-10-26T21:22:50.353 に答える
1

参照カウントされ、使用されなくなるまで割り当てのガベージ コレクションを停止するポインターはreference. 参照を使用すれば、ポインターやunsafeコードが必要になる可能性はほとんどありません。

C# は C ではないため、C コードを作成しようとする場合は注意してください。C# を学習し、これらの言語には明らかな類似性があるにもかかわらず、非常に大きな違いがあることを理解する必要があります。

于 2012-10-26T21:24:06.920 に答える