質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

5回答

866閲覧

メモリの確保について

masuter0413

総合スコア50

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2018/11/21 14:24

ローカル変数はスタック領域に逆順に確保されていくのはなぜでしょうか。
また、```c
int main(){
hoge();
hoge1();
return 0;
}

を実行したときのメモリの中の変化ですが、 まず、main関数の関数フレームがスタック領域にpushされ、つぎにhoge、つぎにhoge1がpushされる。hoge1の呼び出しが終了すると、hoge1をpop、つぎにhoge2,最後にmainをpopするという考えでよろしいでしょうか?FILO方式はこのことですか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cateye

2018/11/21 14:36 編集

失礼、回答に入れました。
guest

回答5

0

C言語レベルで言うと処理系依存なので深く考えず、
「スタック領域があって、引数やローカル変数はそこに置かれる」程度の知識でいいと思います。


x86に限った話としては(私が他の処理系詳しくないだけですが)

関数の途中ではスタックフレームの開始地点はスタックに格納され、出すのに手間が掛かります。
そのため

ローカル変数のアドレスはベースポインタ-定数で表されます。
ベースポインタ-0よりベースポインタ-4の方が小さいので、結果として逆順に見えます。

呼び出しについては、呼び出し規約に依存しますが
提示されたソースの場合は引数がないので、概ね

  1. main関数のスタックフレームが作成される。
  2. hogeが呼び出される(return先として呼び出した次の位置がスタックに記憶される)
  3. hoge関数のスタックフレームが作成される
  4. hoge関数のスタックフレームが破棄される
  5. returnし、呼び出し位置が破棄される
  6. hoge1が呼び出される(return先として呼び出した次の位置がスタックに記憶される)
  7. hoge1関数のスタックフレームが作成される
  8. hoge1関数のスタックフレームが破棄される
  9. returnし、呼び出し位置が破棄される
  10. main関数のスタックフレームが破棄される

の流れです。

引数があった場合は、呼び出し規約に依存します。


余談ですが、FILOよりもLIFOの方が通り名として一般的です。
余談ついでですが、スタックの成長方向も処理系依存です。PA-RISCとやらはx86とは逆方向らしい

投稿2018/11/21 15:04

編集2018/11/21 21:52
asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ローカル変数はスタック領域に逆順に確保されていくのはなぜでしょうか。

正解じゃないかもしれませんが、昔のコンピュータで、スタックオーバーフローを発生させてしまった際に他人のプログラムを壊してしまう可能性を減らしたかったからだと思います。
とりあえず、スタックを底において上方向に成長させれば壊すのは自分のプログラムだけで済みますしね。
現在もそのようになっているのは特に変える理由もないからだと思います。

投稿2018/11/23 08:50

TaroToyotomi

総合スコア1430

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ローカル変数はスタック領域に逆順に確保されていくのはなぜでしょうか。

CPUのスタックという仕組みがそうなってるから、です。
CPUのデータシートを読んでみたらどうでしょう

投稿2018/11/21 14:55

y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

逆順に確保

これは番地(アドレス)の大きい方からと言うことでしょうか?であれば、スタックは上位番地から下に向かって伸びていくからです。
スタック

投稿2018/11/21 14:37

cateye

総合スコア6851

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

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
pepperleaf

総合スコア6383

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問