Code Fix

上級

terminate called after throwing an instance of '...' の原因と直し方

throwで投げた例外をどこのtry-catchでも捕まえられず、プログラム全体が異常終了してしまうバグです。C++のランタイムはstd::terminateを呼び出し、プロセスを強制終了させます。

エラーメッセージの読み方

terminate called after throwing an instance of 'std::runtime_error'
terminate called after throwing an instance of 'std::runtime_error'
ランタイム(または例外機構、assert)が不整合を検知して出したメッセージ
Aborted
この後プロセスは強制終了します(Aborted)

このエラーが出る典型パターン

パターン1

 1  #include <iostream>
 2  #include <stdexcept>
 3  void withdraw(int balance, int amount) {
 4      if (amount > balance) {
 5          throw std::runtime_error("insufficient funds");
 6      }
 7      std::cout << "ok" << std::endl;
 8  }
 9  int main() {
10      withdraw(100 , 500);
                   ^
11      return 0;
12  }
terminate called after throwing an instance of 'std::runtime_error' what(): insufficient funds Aborted

throwで投げた例外をどのtry-catchでも捕まえないと、C++のランタイムはstd::terminateを呼び出しプロセスを強制終了させます。ここでは残高を十分な値にして例外自体が発生しないようにするのが直し方です。

直し方: 1001000 にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  #include <iostream>
 2  #include <stdexcept>
 3  void setAge(int age) {
 4      if (age < 0) {
 5          throw std::invalid_argument("age must not be negative");
 6      }
 7      std::cout << "age set" << std::endl;
 8  }
 9  int main() {
10      setAge(-5);
                ^
11      return 0;
12  }
terminate called after throwing an instance of 'std::invalid_argument' what(): age must not be negative Aborted

「例外はthrowしておけば自動的にどこかで処理される」というのは誤解です。呼び出し元をさかのぼって対応するcatchが見つからなければ、mainまで届いてterminateされます。

直し方: -55 にします。

この問題を解いてみる →

パターン3

 1  #include <iostream>
 2  #include <stdexcept>
 3  void checkStock(int stock, int order) {
 4      if (order > stock) {
 5          throw std::runtime_error("out of stock");
 6      }
 7      std::cout << "shipped" << std::endl;
 8  }
 9  int main() {
10      checkStock(3, 10);
                       ^
11      return 0;
12  }
terminate called after throwing an instance of 'std::runtime_error' what(): out of stock Aborted

例外の中身(what()で得られるメッセージ)はプログラマが自由に決められますが、捕まえられなければ結局terminateで強制終了する点は変わりません。

直し方: 102 にします。

この問題を解いてみる →

よくある誤解

「例外はthrowしておけば自動的にどこかで処理される」というのは誤解です。C++の例外は、呼び出し元をさかのぼって対応するcatchが見つかるまで探されますが、mainまで誰も捕まえなければプログラムはterminateによって強制終了します。

まとめ

terminate called after throwing an instance of '...'は上級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)