エンベデッドシステムスペシャリスト 2019年 午前2 問21
問題文
C言語で作成されたプログラム全体で使用するスタックフレームのサイズが、確保したサイズ内に収まっていることを検証したい。各関数が使用するスタックフレームのサイズ情報に加え、必要となる情報はどれか。
選択肢
ア:各関数が使用するレジスタの退避領域のサイズ
イ:各関数が使用するローカル変数のサイズ
ウ:各関数の呼出し関係(呼出しツリー)(正解)
エ:グローバル変数の合計サイズ
🔒 解説は解答すると表示されます
スタック使用量の検証【午前2解説】
正解の理由
プログラム実行中のスタック使用量は、実行中に同時に存在するスタックフレームの合計で決まります。関数を呼び出すと、呼出し元のスタックフレームを残したまま、呼出し先のフレームが追加されるためです。
したがって、プログラム全体の最大使用量を調べるには、各関数のスタックフレームサイズだけでなく、どの関数がどの関数を呼び出すかという情報が必要です。呼出し関係から呼出し経路をたどり、各経路上のフレームサイズを合計することで、最大のスタック使用量を見積もれます。この情報に当たるのはウです。
解法ステップ
- スタックフレームは、関数呼出しごとに確保される領域だと確認します。
- 関数呼出し中は、呼出し元と呼出し先のフレームが同時にスタック上に存在すると考えます。
- そのため、単純に全関数のフレームサイズを合計するのではなく、実行時に連続して呼び出される関数の経路を調べます。
- 最大の呼出し経路を特定するために、各関数の呼出し関係が必要です。
選択肢別の誤答解説
-
ア:各関数が使用するレジスタの退避領域のサイズ
レジスタ退避領域は、スタックフレームを構成する要素に含まれることがあります。設問では各関数のスタックフレームサイズが分かっているため、追加で必要な情報ではありません。 -
イ:各関数が使用するローカル変数のサイズ
ローカル変数の領域も、通常はスタックフレームのサイズに含まれます。フレームサイズが既知なら、別途ローカル変数のサイズを加える必要はありません。 -
ウ:各関数の呼出し関係(呼出しツリー)
正解です。呼出し元のフレームが残った状態で呼出し先のフレームが追加されるため、同時にスタック上に存在するフレームを調べるには、関数の呼出し関係が必要です。 -
エ:グローバル変数の合計サイズ
グローバル変数は通常、スタックではなく静的記憶域に確保されます。そのため、スタック使用量の検証に必要な情報ではありません。
よくある誤解
-
全関数のフレームサイズを合計すればよい
全関数が同時に実行されるとは限りません。合計するのは、同時に実行中となる関数の呼出し経路上のフレームです。 -
ローカル変数のサイズを、フレームサイズに追加する必要がある
設問では各関数のスタックフレームサイズが与えられています。ローカル変数領域などが含まれたサイズとして扱います。 -
グローバル変数もスタックを消費する
グローバル変数は一般に静的記憶域に配置され、関数呼出しに伴うスタックフレームとは区別されます。
補足コラム
最大スタック使用量は、各関数のフレームサイズを呼出し経路ごとに合計し、その最大値として求めます。たとえば、関数AがBを呼び、BがCを呼ぶ場合、A・B・Cのフレームが同時にスタック上に存在し得ます。
再帰呼出しがある場合は注意が必要です。再帰の深さに上限がなければ、必要なスタック量を有限の値として確定できないことがあります。その場合は、再帰回数の上限なども考慮します。
FAQ
Q. すべての関数のサイズを合計する必要はありませんか?
A. ありません。すべての関数が同時に呼び出されるわけではないため、呼出し経路上で同時に存在するフレームを合計します。
A. ありません。すべての関数が同時に呼び出されるわけではないため、呼出し経路上で同時に存在するフレームを合計します。
Q. 呼出しツリーが分かれば、最大サイズを必ず求められますか?
A. 各関数のフレームサイズと呼出し関係に加え、再帰がある場合はその深さの上限も必要です。
A. 各関数のフレームサイズと呼出し関係に加え、再帰がある場合はその深さの上限も必要です。
関連キーワード: スタックフレーム、呼出しツリー、スタック使用量、再帰呼出し、静的記憶域

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

