エンベデッドシステムスペシャリスト 2016年 午前2 問24
問題文
C言語で作成されたプログラム全体で使用するスタックフレームのサイズが、確保したサイズ内に収まっていることを検証したい。各関数が使用するスタックフレームのサイズ情報に加え、必要となる情報はどれか。
選択肢
ア:各関数が使用するレジスタの退避領域のサイズ
イ:各関数が使用するローカル変数のサイズ
ウ:各関数の呼出し関係(呼出しツリー)(正解)
エ:グローバル変数の合計サイズ
🔒 解説は解答すると表示されます
スタックフレームの総使用量検証【午前2解説】
正解の理由
プログラム全体で必要となるスタックサイズを調べるには、各関数のスタックフレームのサイズに加えて、関数がどのような順序で呼び出されるかを知る必要があります。
関数を呼び出すと、その関数のスタックフレームがスタックに積まれます。呼出し元のフレームは、呼び出した関数の処理が終わるまで残ります。そのため、同時にスタック上に存在するフレームは、実行時の呼出し経路上にある関数のものです。
したがって必要なのは、各関数の呼出し関係を示す情報です。これに該当するウを使えば、呼出し経路ごとにフレームサイズを合計し、必要なスタックサイズを検討できます。
解法ステップ
- 各関数のスタックフレームサイズは、問題文で分かっていると確認します。
- スタックに同時に積まれるのは、呼出し中の関数と、その呼出し元の関数のフレームだと考えます。
- どの関数がどの関数を呼び出すかを把握し、呼出し経路ごとのサイズを合計する必要があります。
- よって、追加で必要な情報は関数の呼出し関係です。
選択肢別の誤答解説
-
ア:各関数が使用するレジスタの退避領域のサイズ
レジスタの退避領域は、関数のスタックフレームの一部として扱われます。フレームサイズが既に分かっているなら、別途必要な情報ではありません。 -
イ:各関数が使用するローカル変数のサイズ
ローカル変数も通常はスタックフレーム内に確保されます。各関数のフレームサイズが分かっているため、個別に追加する必要はありません。 -
ウ:各関数の呼出し関係(呼出しツリー)
正しい選択肢です。呼出し経路をたどることで、同時にスタック上に存在するフレームの組合せを判断できます。 -
エ:グローバル変数の合計サイズ
グローバル変数は通常、スタックではなく静的領域に格納されます。そのため、スタックサイズの検証に必要な情報ではありません。
よくある誤解
-
すべての関数のフレームサイズを合計すればよい
すべての関数が同時に実行されるわけではありません。合計するのは、実行時に同時に呼出し中となる関数のフレームです。 -
ローカル変数のサイズも別に加える必要がある
フレームサイズがローカル変数などを含む値であれば、二重に加算してはいけません。 -
関数の呼出し関係が分かれば、再帰の影響も必ず確定する
再帰呼出しでは、同じ関数のフレームが複数積まれる場合があります。最大再帰深さが不明なら、必要なスタックサイズを確定できないことがあります。
補足コラム
スタック使用量は、関数呼出しの深さに応じて増加します。例えば、関数Aが関数Bを呼び、Bが関数Cを呼ぶ場合、A・B・Cのフレームが同時にスタック上に存在し得ます。一方、AからBとCを順番に呼び出すだけなら、通常、BとCのフレームが同時に積まれることはありません。
FAQ
Q. 呼出しツリーのどこを見ればよいですか?
A. 呼出し経路ごとにフレームサイズを合計し、その中で最大となる経路を確認します。
A. 呼出し経路ごとにフレームサイズを合計し、その中で最大となる経路を確認します。
Q. グローバル変数が多いとスタックも大きくなりますか?
A. 通常はなりません。グローバル変数は静的領域に置かれ、スタックとは別に管理されます。
A. 通常はなりません。グローバル変数は静的領域に置かれ、スタックとは別に管理されます。
関連キーワード: スタックフレーム、スタック領域、関数呼出し、呼出しツリー、再帰呼出し

\ せっかくなら /
エンベデッドシステムスペシャリストを
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

