※本記事は広告を含みます。
メモリ領域解説シリーズ
本記事は「メモリ領域解説」シリーズの1つです。
関数を呼び出すと、スタック領域にはどのようなデータが積まれるのでしょうか。
C言語では関数呼び出しのたびに、スタック上に**スタックフレーム(Stack Frame)**と呼ばれる領域が作られます。
このスタックフレームには次のような情報が保存されます。
- 関数の引数
- ローカル変数
- 戻りアドレス
- 退避されたレジスタ
これを理解すると、
- なぜ再帰が動くのか
- なぜローカル変数は関数終了で消えるのか
- スタックオーバーフローはなぜ起きるのか
といった仕組みが見えてきます。
今回は、C言語の関数呼び出しとスタックフレームの関係を図を使って整理します。
初心者さん先輩、スタック領域の記事で“関数呼び出しごとにデータが積まれる”ってありましたよね。
あれって具体的に何が積まれてるんですか?



いい質問だね。それがスタックフレームなんだ。



フレーム?



関数1回分の作業スペースみたいなもの。
関数が呼ばれると、その関数専用のメモリ領域がスタックに作られるんだ。
スタックフレームとは
スタックフレームとは、関数呼び出し1回分のデータを保存する領域です。
関数が呼び出されると、スタックに新しいフレームが作られます。
main()
└ funcA()
└ funcB()このように関数が呼ばれると、スタックは次のようになります。
+----------------+
| funcB frame |
+----------------+
| funcA frame |
+----------------+
| main frame |
+----------------+最後に呼ばれた関数のフレームが、スタックの一番上に積まれます。
スタックフレームに入るもの
スタックフレームには主に次の情報が入ります。
1. 戻りアドレス
関数が終了した後、どこに戻るかを示すアドレスです。
main → funcAfuncAが終わったら、mainの続きに戻ります。
そのため、戻り先を保存しておく必要があります。
2. 関数の引数
関数に渡された引数もスタックに保存されます。
void func(int a, int b)この a と b がスタックフレームに配置されます。
3. ローカル変数
関数内で宣言した変数です。
void func() {
int x = 10;
}この x はスタックフレーム内に保存されます。
関数が終了すると、フレームが破棄されるため
ローカル変数も消えます。
図:スタックフレームのイメージ
+----------------------+
| ローカル変数 |
+----------------------+
| 保存されたレジスタ |
+----------------------+
| 戻りアドレス |
+----------------------+
| 関数の引数 |
+----------------------+このまとまりが1つのスタックフレームです。
再帰が動く理由
スタックフレームがあるおかげで、同じ関数でも複数回呼び出せます。
例:
factorial(3)呼び出しのイメージ
factorial(3)
factorial(2)
factorial(1)スタックは次のようになります。
+--------------+
| factorial(1) |
+--------------+
| factorial(2) |
+--------------+
| factorial(3) |
+--------------+それぞれの呼び出しが別のスタックフレームを持つため、
計算が独立して実行できます。
スタックオーバーフローとの関係
スタックフレームは関数呼び出しごとに増えます。
そのため、
- 無限再帰
- 深すぎる再帰
が起きると、スタックがあふれてしまいます。
これが **スタックオーバーフロー(Stack Overflow)**です。
まとめ
スタックフレームとは、関数呼び出し1回分のデータを保存する領域です。
スタックフレームには次の情報が含まれます。
- 戻りアドレス
- 引数
- ローカル変数
- 保存されたレジスタ
関数呼び出しのたびにスタックに積まれ、
関数終了時に破棄されます。
この仕組みを理解すると、C言語の関数呼び出しや
スタックの動作がより明確になります。
この記事が参考になった方へ
メモリ領域については他の記事でも解説しています。
技術に関するご相談・開発・自動化ツール作成・記事執筆などのご依頼も承っています。
小さなご相談からでもお気軽にご連絡ください。









コメント