1

混乱して申し訳ありませんが、C ++では、ローカル変数の参照を返すか、ポインターがbad_reference例外を引き起こす可能性があることを知っています。C#でどうなっているのかわかりませんか?

例えば

List<StringBuilder> logs = new List<StringBuilder>();
void function(string log)
{
   StringBuilder sb = new StringBuilder();
   logs.Add(sb);
}

この関数では、ローカルオブジェクトが作成されてリストに格納されますが、それは悪いことであるか、別の方法で実行する必要があります。これを聞いて本当に申し訳ありませんが、C++を2か月間コーディングした後混乱しています。

ありがとう。

4

4 に答える 4

1

C#コードはオブジェクト参照を返さないため、懸念事項と一致しません。ただし、C#には存在しない問題です。CLRでは、スタック上にオブジェクトを作成することはできず、ヒープのみを作成できます。また、ガベージコレクターは、オブジェクト参照が有効なままであることを確認します。

于 2012-07-23T17:04:19.330 に答える
1

C#では、ガベージコレクターは、作成したすべての(管理対象)オブジェクトを管理します。参照がなくなっていない限り、削除されません。

そのため、そのコードは完全に有効です。logsへの参照を保持しますStringBuilder。ガベージコレクターはこれを認識しているため、最初に作成されたコンテキストがスコープ外になった後でも、ガベージコレクターはクリーンアップしません。

于 2012-07-23T17:05:55.223 に答える
1

C#では、オブジェクトのライフサイクルはCLRによって管理されます。それぞれの新しいものを削除と一致させる必要があるC++と比較して。

ただし、C#では実行できません

void fun()
{
    SomeObject sb(10);
    logs.Add(sb);
}

つまり、スタックに割り当てるにはnewを使用する必要があります。したがって、この点では、オブジェクト参照の解放/解放を除いて、C#とC++の両方が同様に機能します。

C#でもメモリをリークする可能性はありますが、C++よりも困難です。

于 2012-07-23T17:06:10.557 に答える
1

あなたが書いたコードには何の問題もありません。これは主に、C#が、他の.NET言語と同様に、多くのメモリ管理を行う「管理された」言語であるためです。C ++で同じ効果を得るには、サードパーティのライブラリを明示的に使用する必要があります。

あなたのためにいくつかの基本をクリアするには:

C#では、「ポインタ」や「参照」を直接扱うことはめったにありません。必要に応じてポインタを処理できますが、これは「安全でない」コードであり、何をしているのかを理解していない限り、そのようなことは避けてください。参照(refまたはoutパラメーターなど)を処理するいくつかのケースでは、言語はすべての詳細を非表示にし、それらを通常の変数として扱うことができます。

代わりに、C#のオブジェクトは参照型のインスタンスとして定義さます。参照型のインスタンスを使用するときはいつでも、詳細を気にする必要がないことを除いて、ポインターを使用するのと似ています。C ++でオブジェクトの新しいインスタンスを作成するのと同じ方法で、メモリの割り当てやコンストラクターの実行などを行う演算子を使用して、C#で参照タイプの新しいインスタンスを作成します。コードサンプルでは、​​とは両方とも参照タイプです。newStringBuilderList<StringBuilder>

ここで重要な管理言語の重要な側面は、自動ガベージコレクションです。実行時に、.NET Frameworkは、作成したオブジェクトを「認識」します。これは、オブジェクトを常に独自の内部管理ヒープから作成しているためです(mallocC#では直接またはそのようなものはありません)。また、オブジェクトが完全にスコープから外れたとき、つまりプログラム内のどこにもオブジェクトへの参照がなくなったときを「認識」します。これが発生すると、ランタイムは必要なときにいつでもメモリを解放できます。通常、空きメモリが不足し始めたときに、実行する必要はありません。実際、C#には、管理対象オブジェクトを明示的に破棄する方法はありません(ただし、管理対象外のリソースを使用する場合は、それらをクリーンアップする必要があります)。

あなたの例では、ランタイムはあなたがを作成し、それを;StringBuilderに入れたことを知っています。List<>それはそのオブジェクトを追跡し、それがその中にある限り、List<>それは固執します。から削除するList<>か、List<>それ自体がなくなると、ランタイムが自動的にクリーンアップStringBuilderします。

于 2012-07-23T17:14:05.847 に答える