2

私の理解では、通常、各スレッドは 1 つのスタックのみを取得します (通常、プロセス内のすべてのスレッドはヒープを共有します)。関数呼び出しが発生したときにプログラムカウンター(PC)の値を格納するためにスタックが使用されるといつも思っていました。integerしかし、その後、またはなどの特定の変数タイプbooleanがスタックにも割り当てられていることをどこかで読みました。スタック上の値は厳格な FILO 方式で管理されているため、これらの変数をいつでも取得するにはどうすればよいでしょうか?

たとえば、 を宣言した後int a, b, c;、これらの変数に対して、スコープ内でいつでも任意の順序で好きなことを行うことができます。これはどのように行われますか?cスタックの一番上に値がなく、したがって値が隠されているのはなぜa, bですか?

4

3 に答える 3

1

まず最初に、スタック全般についてもう少し調査することをお勧めします(Wikipediaスタックの説明などをグーグル/ CSブックで参照してください)。

ただし、特定の質問については、ヒープで生成されないすべての変数がスタックにあります。newこれには通常、( C ++およびJavaの演算子を介して)直接ヒープに割り当てられていない特定の関数内で定義したものがすべて含まれます。一部の言語では、すべてがヒープに割り当てられ、それらのヒープ構造へのポインターのみがスタックに格納されます(Pythonの場合のように)。言語間でこれらのさまざまな小さな変更が表示されます。

したがって、整数とブール値が常にスタック上にあるという記述は正しくありません。関数内で定義した場合はスタック上にあり、でビルドした場合はヒープ上にありますnewintJavaでは、プリミティブを使用する場合、通常はスタックベースであり、オブジェクトはヒープベースであることに注意してください。ただしInteger、これは、基本的なスタックの知識を超えた、Javaのより高度なニュアンスです。

同じスコープ内のすべてにアクセスできますint a, b, c;。これは、その関数スタックスコープ内の3つの変数すべてのためのスペースを確保するためです。関数が戻ると、スタックが上に移動するときにこれらの変数がクリーンアップされます。その時点まで、スコープブロック全体がスタックのFILO構造の一部であり、戻るまで存続するため、3つすべてが存在します。

于 2012-09-05T16:47:35.357 に答える
1

コール スタックは、ローカル変数にも使用され、パラメーターを関数に渡すためにも使用されます。

「値型」はスタックに渡されますが、参照型はヒープに割り当てられますが、参照型がパラメーターとして使用される場合、このヒープの場所へのポインターは引き続きスタックに渡されます。

スタックは通常 LIFO バッファとして「認識」されますが、現在のスタック ポインタの上または下のメモリに直接アクセスするために使用できるコール スタックに関連付けられたフレームまたはベース ポインタもあります。これは、関数がスタック ポインターを変更せずにパラメーターにランダム アクセスできる方法です。

ウィキペディアのこの図は、これを視覚化するのに役立つかもしれませんが、スタックは「下向き」に成長するべきだと主張する人が多いことに注意してください。

このブログ投稿は、インテルのコールスタックについて説明しています

于 2012-09-05T16:44:09.490 に答える
1

作業している環境に応じて、その質問には多くの答えがあります。確かに、(機械語の POP および PUSH で使用される) 命令で使用されるスタック (より正確にはスタックフレーム) と同じように、プロセッサ スタックを同一視するべきではありません。 Python インタープリターや .net ランタイムのようなもの

しかし、短い答えは、スタックの一番上は単なるメモリの場所であるため、単にオフセットを使用することです

a、b、cを押した場合

したがって、b のアドレスはスタック アドレス - 4 になります。

于 2012-09-05T16:50:48.150 に答える