0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

C++で例外をcatchしないとどうなるか?実行時エラーとその対処法

Last updated at Posted at 2025-03-21

✅発生したエラーとその意味

terminate called after throwing an instance of 'std::invalid_argument'
  what():  0より大きい数値を入力してください。
run: line 1:     3 Aborted                 (core dumped) LD_LIBRARY_PATH=/usr/local/gcc-9.2.0/lib64 ./a.out
  • terminate called after throwing an instance of 'std::invalid_argument'

std::invalid_argument 型の例外が投げられた(throwされた)あとに、terminate() が呼ばれて異常終了したことを示している。

  • what(): 0より大きい数値を入力してください。

    throw 時に渡したメッセージ(what() の中身)が表示されている。

    つまり、例外オブジェクトがなぜエラーなのかを伝えてくれている部分。

  • Aborted (core dumped)

    → 例外が捕まえられなかった(catchされなかった)ため、プログラムがクラッシュ(Abort)して、メモリダンプが出力されたことを示している。

⚠️ 原因

以下のコード内でthrowによって例外(std::invalid_argument)が投げられているが、main()関数内でtry-catchによる処理がされていなかったため、プログラムが例外未処理のまま異常終了した。

if (val <= 0) {
    throw std::invalid_argument("0より大きい数値を入力してください。");
}

🛠 解決策

  • 大前提:例外を投げたら必ずどこかで受け取って処理すること。
  • 例外が発生する可能性のある関数を呼び出す時は、try-catch文で囲んで例外を適切に処理すること。
  • これにより、プログラムのクラッシュが防ぎ、ユーザーに適切なエラーメッセージを提示できる。
  • また、what()を使えば、例外の詳細なメッセージを取得可能。

✅修正後のコード例

#include <iostream>
#include <string>
#include <stdexcept>

std::string convertVal (int val, std::string type) {
    std::string result;
    int divisor;

    // 例外処理
    if (val <= 0) {
        throw std::invalid_argument("0より大きい数値を入力してください。");
    }

    // 16進数に変換する場合
    if (type == "hex") {
        divisor = 16;
    // 2進数に変換する場合
    } else if (type == "bits") {
        divisor = 2;
    }   

    // 以下で余りを16進数や2進数に変換していく
    while (val > 0) {
        int remaind = val % divisor;

        if (type == "hex" && remaind >= 10) {
            int diff = remaind - 10;
            char hex = 'A';
            hex += diff;
            result = hex + result;
        } else {
            result = std::to_string(remaind) + result;
        }

        val /= divisor;
    }

    return result;
}

int main () {

    try {
        std::cout << convertVal(0, "bits") << std::endl;
    } catch (const std::invalid_argument& e) {
        std::cerr << "入力エラー" << e.what() << std::endl;
        return 1;
    }

    return 0;
}

💡補足

  • catchではconst std::invalid_argument& eのように「const参照」で受け取ることで、無駄なコピーを避けつつ安全に例外メッセージを参照できる。
  • そもそもエラーとは、プログラムが正常に動かない状況全般のこと。その中で、意図的に throw できて、try-catch で対応できるものを「例外」と呼ぶ。
  • Pythonのようなインタプリタ言語は、例外を自動で発生させてくれる場面が多いが、C++のようなコンパイル言語では、開発者が自分で throw して例外処理を書く必要がある。
  • 例外処理の目的は、プログラムのクラッシュを未然に防いだり、安全に終了したり、代替処理を入れたりするため。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?