TopC++ 入門 › エラー辞典 › 実行時

C++ 実行時エラー辞典 — よく出る 16 種

コンパイルが通っても実行中に落ちる。その多くは未定義動作 (UB) かライブラリの例外です。典型パターンを見て慣れれば、再発生時に数秒で「ああ、これ」と気付けるようになります。

すべて メモリ ライブラリ例外 並行 数値

memR01. SEGV — ヌルポインタ参照

Segmentation fault (core dumped)

原因: nullptr-> / * で辿った。実行時ログに出ないので、gdb で bt するのが王道。

ng.cppUB
Widget* p = nullptr; p->show(); // SEGV
ok.cppOK
if (p) p->show(); // 所有したいなら std::unique_ptr
検出: gdb / ASan

memR02. SEGV — ダングリングポインタ

原因: 解放済みメモリ / スコープ外のローカル変数を参照。

ng.cppUB
int* bad() { int x = 5; return &x; // スコープ外 }
ok.cppOK
int good() { return 5; } // または shared_ptr で寿命共有
検出: AddressSanitizer

memR03. ヒープバッファオーバーラン

原因: 確保したサイズを越える書き込み。C の strcpy や C++ でも new int[10] に 10 番目を書く等。vector::atvector 自体への置き換えが根本策。

ng.cppUB
int* a = new int[5]; a[5] = 0; // 1 個はみ出し
ok.cppOK
std::vector<int> a(5); a.at(5); // out_of_range を投げる
検出: ASan

memR04. use-after-free

原因: delete 後のポインタにアクセス。iterator 無効化もこのカテゴリ。

検出: ASan

memR05. double free

原因: 同じポインタを 2 回 delete。unique_ptr / shared_ptr でほぼ消せる。

検出: ASan / glibc の runtime check

memR06. iterator 無効化クラッシュ

原因: vector::push_back で再配置が起きると既存イテレータは全て無効。無効なイテレータを * すると未定義。

ng.cppUB
auto it = v.begin(); v.push_back(9); // 再配置で it 無効 *it; // UB
ok.cppOK
v.reserve(100); // 先に予約 auto it = v.begin(); v.push_back(9);
検出: libstdc++ の _GLIBCXX_DEBUG

libR07. std::bad_alloc

terminate called after throwing an instance of 'std::bad_alloc'

原因: new がメモリ確保に失敗。32-bit 環境や組込で出やすい。サイズを確認するか、new (std::nothrow) で nullptr 戻り値を選ぶ。

libR08. std::out_of_range(at / substr)

terminate called: std::out_of_range: vector::_M_range_check

原因: at(i) が範囲外。operator[] は未定義(ASan 推奨)。

libR09. std::bad_optional_access

terminate called: std::bad_optional_access

原因: 空の optional.value()value_or() か事前 if 判定。

libR10. std::bad_variant_access

原因: variant の現在の型と違う型で get<T>holds_alternativevisit を使う。

libR11. std::terminate() 呼び出し

原因: 捕まえられない例外 / デストラクタから例外 / noexcept 関数が投げた / std::thread 未 join。バックトレースで直上の throw を探す。

thR12. データ競合によるデータ破壊

原因: 複数スレッドが同じ変数を読み書き。値がじわじわおかしくなる(再現性低)。ThreadSanitizer(-fsanitize=thread)で検出。

検出: TSan

thR13. デッドロック(ハング)

原因: 循環するロック順序。std::scoped_lock を使うか、プロセス全体でロック順を統一する。

検出: TSan / gdb info threads

numR14. 整数オーバーフロー(signed)

原因: signed int の最大値を超えると UB(unsigned はラップ)。-fsanitize=undefined で検出できる。std::clamp / __builtin_add_overflow で安全に。

検出: UBSan

numR15. ゼロ除算

原因: 整数の x / 0 は UB。浮動小数の 0.0/0.0 は NaN(これは UB ではない)。

検出: UBSan

memR16. stack overflow(再帰深すぎ)

原因: 無限再帰 or 巨大配列をスタックに。スタック上のサイズ上限は通常 1〜8 MB。巨大配列は std::vector へ。