C++デバッガのエラーコード・終了シグナル
RE原因究明・判定のトラブルシューティング
オンラインジャッジ(AtCoderなど)での提出時、意図しない挙動やプログラムの異常終了が発生した際に、その原因を特定するための参照表です。 (あんまり必要ないかもしれないけど...。)
オンラインジャッジの判定一覧
提出コードが実行された結果として返ってくる代表的な判定(Verdict)とその主な原因です。
| 判定 | 英語名 | 主な原因と対策 |
|---|---|---|
| AC | Accepted | 提出したプログラムがすべてのテストケースに対して正しく動作しました。 |
| WA | Wrong Answer | 出力された答えが正しくありません。コーナーケース、初期化漏れ、整数オーバーフローを確認してください。 |
| TLE | Time Limit Exceeded | 実行時間制限を超過しました。無限ループや計算量の見積もりミス(目安:1秒間に $10^8$ 回の計算)がないか確認しましょう。 |
| MLE | Memory Limit Exceeded | 使用メモリ制限を超過しました。巨大な配列や動的確保、再帰のメモリ消費量が多すぎる可能性があります。 |
| RE | Runtime Error | プログラムが実行途中に異常終了しました。不正なメモリへのアクセス、ゼロ除算などが原因です。 |
| CE | Compilation Error | コンパイルに失敗しました。手元のコンパイラと言語バージョン(C++20等)が一致しているか確認してください。 |
REシグナル一覧
プログラムがREを起こした際、シグナルや終了コードからエラーの具体的な原因を絞り込むことができます。
| シグナル名 | 終了コード | 一般的な原因 | 具体的な対策 |
|---|---|---|---|
| SIGSEGV | 139 (11) | セグメンテーション違反 / 不正なメモリアクセス | 配列の範囲外参照、配列サイズ不足、ぬるぽ、スタックオーバーフローなど。 |
| SIGFPE | 136 (8) | 浮動小数点例外 / 算術エラー |
ゼロでの除算(a / 0)、ゼロでの剰余(a % 0)が典型例。
|
| SIGABRT | 134 (6) | プログラムの異常終了(アボート) |
assert()の失敗、std::vector::at()の例外、メモリ確保失敗。
|
| SIGILL | 132 (4) | 不正な命令(Illegal Instruction) | 未定義動作を踏んだ、またはコンパイラ最適化による異常検知。 |
| SIGKILL / SIGXCPU | 137 / 152 | 強制終了(メモリ超過・時間超過) | 環境によってはTLEやMLEがシグナルとして返ってきます。 |
オーバーフローとエラーコードの関係
スタックオーバーフロー(Stack Overflow)
再帰関数(DFSなど)が深すぎる場合や、巨大な配列をローカル変数としてスタック領域に配置した場合に発生。
-
検知されるシグナル:
SIGSEGV(終了コード: 139) -
対策:
-
配列はグローバル変数にする、または
std::vectorでヒープ領域に動的確保する。 -
再帰関数のループ化(スタックの代わりを自前の
std::stackで表現する)。
-
配列はグローバル変数にする、または
整数オーバーフロー(Integer Overflow)
int
などのデータ型の上限を超えて演算した際に発生。
- 検知されるシグナル: 原則としてなし(WAになる)
-
詳細:
C++などでは、符号付き整数のオーバーフローは未定義動作(UB)だが、多くの場合エラーを出さずに値が折り返され(負の値などになり)、そのまま処理が続行される。結果、出力がおかしくなり
WAとなる。これは、デバッガで対策するべき。 -
対策:
- repの中身とか、ライブラリの中身にintが潜んでいるかもしれない。あるいは、シンプルにもっとオーバーフローしてるだけかも。
-
1LL << nのように、リテラルにLLをつけないとエラーが出る(1敗)。