ローカル変数はスタック領域に逆順に確保されていくのはなぜでしょうか。
また、```c
int main(){
hoge();
hoge1();
return 0;
}
を実行したときのメモリの中の変化ですが、 まず、main関数の関数フレームがスタック領域にpushされ、つぎにhoge、つぎにhoge1がpushされる。hoge1の呼び出しが終了すると、hoge1をpop、つぎにhoge2,最後にmainをpopするという考えでよろしいでしょうか?FILO方式はこのことですか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答5件
0
C言語レベルで言うと処理系依存なので深く考えず、
「スタック領域があって、引数やローカル変数はそこに置かれる」程度の知識でいいと思います。
x86に限った話としては(私が他の処理系詳しくないだけですが)
関数の途中ではスタックフレームの開始地点はスタックに格納され、出すのに手間が掛かります。
そのため
ローカル変数のアドレスはベースポインタ-定数で表されます。
ベースポインタ-0よりベースポインタ-4の方が小さいので、結果として逆順に見えます。
呼び出しについては、呼び出し規約に依存しますが
提示されたソースの場合は引数がないので、概ね
- main関数のスタックフレームが作成される。
- hogeが呼び出される(return先として呼び出した次の位置がスタックに記憶される)
- hoge関数のスタックフレームが作成される
- hoge関数のスタックフレームが破棄される
- returnし、呼び出し位置が破棄される
- hoge1が呼び出される(return先として呼び出した次の位置がスタックに記憶される)
- hoge1関数のスタックフレームが作成される
- hoge1関数のスタックフレームが破棄される
- returnし、呼び出し位置が破棄される
- main関数のスタックフレームが破棄される
の流れです。
引数があった場合は、呼び出し規約に依存します。
余談ですが、FILOよりもLIFOの方が通り名として一般的です。
余談ついでですが、スタックの成長方向も処理系依存です。PA-RISCとやらはx86とは逆方向らしい
投稿2018/11/21 15:04
編集2018/11/21 21:52総合スコア15147
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ローカル変数はスタック領域に逆順に確保されていくのはなぜでしょうか。
正解じゃないかもしれませんが、昔のコンピュータで、スタックオーバーフローを発生させてしまった際に他人のプログラムを壊してしまう可能性を減らしたかったからだと思います。
とりあえず、スタックを底において上方向に成長させれば壊すのは自分のプログラムだけで済みますしね。
現在もそのようになっているのは特に変える理由もないからだと思います。
投稿2018/11/23 08:50
総合スコア1430
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
push, push, push, pop, pop, pop と利用するのがスタックで、
push, push, push, ... とし、先頭から読出すのが、キューですが?
FILO ... First In, Last Out ですから、その通りでしょう。
スタック構造を使えば、関数呼び出しが簡単にできるという事です。
[追記]
最近のCPUでは確認してませんが、、、スタック操作は専用命令があり、処理が楽。
スタックポインタ更新(減算)、スタックにデータを置く。
スタックを読出し、スタックポインタ更新(加算)。
スタックポインタからのオフセットアクセス。
それぞれが、一命令。
まあ、CPU依存ですが、Intelに関しては、x86互換が基本なので、変わらないと思います。
単にローカル変数をスタックじゃないところに置いても良いですが、スタックに置いた方が楽と思います。また、再帰関数なんて、スタックを使わずに実装するなんてどうすれば、良いのでしょうか。
(きっと方法はあると思うが、思いつかない)
また、ローカル変数をスタックに置くと、関数を抜ける時の後始末が楽というのがあります。(スタックポインタ操作だけ)
スタックとヒープですが、一つのメモリ領域を先頭(アドレスの小さい方)から、ヒープで、最後(アドレスの大きい方)から、スタックに割り当てるのが、昔の一般的割当て。(今も同じ?)
スタック領域に逆順に確保
これは処理系(コンパイラ)依存と思います。
コンパイラによっては、ローカル変数以外にも作業用の内部変数を使うものもあります。それらの変数は、ソースには無くても、スタック上に確保され、使われています。また、レジスタに割り当てられ、スタック上に領域が確保されない場合もあります。
投稿2018/11/21 14:30
編集2018/11/23 11:02総合スコア6383
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。