エンベデッドシステムスペシャリスト 2022年 午前2 問21
問題文
プログラム言語Cで作成されたプログラム全体で使用するスタックフレームのサイズが、確保したサイズ内に収まっていることを検証したい。各関数が使用するスタックフレームのサイズ情報に加えて、必要となる情報はどれか。
選択肢
ア:各関数が使用するレジスタの退避領域のサイズ
イ:各関数が使用するローカル変数のサイズ
ウ:各関数の呼出し関係(呼出しツリー)(正解)
エ:グローバル変数の合計サイズ
🔒 解説は解答すると表示されます
スタック使用量の検証【午前2解説】
正解の理由
スタックには、関数を呼び出すたびに、その関数のスタックフレームが積み重なります。そのため、プログラム全体で必要となるスタックサイズは、各関数のフレームサイズだけでは決まりません。どの関数がどの関数を呼び出すかという関係も必要です。
呼出し関係をたどり、同時に実行中となる関数のスタックフレームサイズを合計します。その合計が最大となる呼出し経路を特定し、確保したスタックサイズに収まるかを確認します。この関係を示す情報が必要なので、ウが正解です。
解法ステップ
- 関数ごとのスタックフレームサイズが分かっていることを確認します。
- 関数の呼出し関係をたどり、同時にスタック上に存在する関数を特定します。
- 呼出し経路ごとに、各関数のスタックフレームサイズを合計します。
- 合計の最大値が、確保済みのスタックサイズを超えないか確認します。
たとえば、関数Aが関数Bを呼び、Bが関数Cを呼ぶ場合、A・B・Cのフレームサイズが同時にスタックを使用します。したがって、各関数のサイズに加えて呼出し関係が必要です。
選択肢別の誤答解説
- ア:レジスタの退避領域は、関数のスタックフレームを構成する情報の一部です。各関数のスタックフレームサイズが分かっているなら、別途必要な情報ではありません。
- イ:ローカル変数の領域も、通常はスタックフレームに含まれます。フレームサイズが既知であれば、改めてローカル変数のサイズを確認する必要はありません。
- ウ:呼出し関係を使って、同時に積み重なるフレームを特定できます。最大のスタック使用量を求めるために必要な情報です。
- エ:グローバル変数は通常、スタックではなく静的データ領域に確保されます。したがって、スタックサイズの検証には直接関係しません。
よくある誤解
- 関数ごとのフレームサイズの最大値だけを見ればよい
関数の呼出しが連続すると、複数のフレームが同時にスタック上に積まれます。呼出し経路上の合計を考える必要があります。 - ローカル変数のサイズを足せばよい
ローカル変数はフレームサイズに含まれるため、既知のフレームサイズに重ねて足すと二重計上になります。 - グローバル変数もスタックを使用する
グローバル変数は通常、スタックとは別の領域に配置されます。
補足コラム
関数が再帰呼出しを行う場合、呼出し関係だけでなく、再帰の最大回数もスタック使用量に影響します。再帰の深さに上限がない場合、必要なスタックサイズを静的に確定できないことがあります。そのため、再帰の上限や入力条件も確認します。
FAQ
Q. 関数を呼び出した後、呼出し元のフレームはスタックから取り除かれますか?
A. いいえ。呼出し先の関数が実行されている間、呼出し元のフレームはスタック上に残ります。そのため、呼出し経路上のフレームサイズを合計します。
A. いいえ。呼出し先の関数が実行されている間、呼出し元のフレームはスタック上に残ります。そのため、呼出し経路上のフレームサイズを合計します。
Q. グローバル変数のサイズは、プログラムのメモリ使用量に関係しないのですか?
A. メモリ使用量には関係しますが、通常はスタックではなく静的データ領域に配置されるため、スタック使用量の計算には含めません。
A. メモリ使用量には関係しますが、通常はスタックではなく静的データ領域に配置されるため、スタック使用量の計算には含めません。
関連キーワード: スタック、スタックフレーム、関数呼出し、呼出しツリー、再帰呼出し

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

