4

このトピックに関するさまざまな記事/ページを読んでいて、最終的にこの記事にたどり着き、混乱しました!

この記事ではValue Types always go where they were declared、著者が意味したことは、値の型が宣言されている方法/場所に応じて、スタックまたはヒープのいずれかに存在する可能性があることです。

わかりやすくするために、コード スニペットを下に置いておきます。

public class Test
{
    int testInt;
    string testString;
}

int anInt;
string aString;
Test testObj;
testObj = new Test();

これらのコード行を実行すると、メモリ割り当ては次のようになります。

ここに画像の説明を入力

構造体はクラスtestIntで宣言されているため、ヒープに格納されます。Test

この例を念頭に置いて、整数を宣言している場所の背後にある単純な Form.cs コードを見てみましょう。

using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public int anotherInt;
    }
}

私の混乱の部分:

この場合、どこにanotherInt割り当てられますか?スタックまたはヒープ?見た目からして、「スタック」という回答がほとんどだと思います。しかし、この変数は というクラスで宣言されていませんForm1か? では、上記の最初のコード スニペットのように、ヒープに移動するべきではありませんか? はいの場合、構造体がスタックに割り当てられるのはどのような状況ですか? メソッド内で宣言されている場合のみ?それでも、メソッドはクラスの下に来るのではないでしょうか?クラスはヒープに格納する必要があります。

知ってる疑問がいっぱい!しかし、何が起こっているのか知りたいだけです。私の質問が明確であることを願っています。

4

2 に答える 2

2

あなたの例anotherIntでは、のインスタンスの残りの部分と一緒にヒープ上に配置されますForm1(もちろん1つ作成すると仮定します)。

ローカルintを作成するには、変数をメソッドまたはプロパティで宣言する必要があります。例えば

void Foo()
{
    int localInt = 42;
}

さて、値型がメソッドで宣言されているからといって、必ずしもそれがスタックにあることを意味するわけではありません。たとえば、キャプチャされた変数は異なる方法で処理されます。

于 2012-12-18T15:57:02.373 に答える
2

あなたの例anotherIntでは、ヒープに割り当てられます。これは、ヒープ割り当てオブジェクトであるanotherIntのフィールドであるためです。Form1スタックはスレッドに関連付けられており、現在実行中のコードに必要な参照/オブジェクトのみが含まれています。したがって、クラスの下にあるメソッドについての質問に答えるには、完全に正しいわけではありません。

メソッドはクラスに属していますが、クラスに直接関連付けられているメモリ ブロックではなく、コードの実行可能ブロックです (これが何であるかanotherInt)。このタイプの割り当てを調べる最善の方法の 1 つは、WinDbg などのメモリ デバッガを使用して、スレッド スタックとヒープを実際に調べることです。これにより、特定の構造体が実際に割り当てられている場所を最も明確に把握できます。

非常に単純化した意味で: スタック = 現在実行中のコード スタックに必要なアドレス、ヒープ = その他すべて。しかし、究極のジョン B は、エリックのブログへのリンクでスポットを当てています。オブジェクトがどこに割り当てられているかを知る必要はありません。

編集:ブログのリンクを含めます。

于 2012-12-18T15:49:30.170 に答える