404 Not Found

404 Not Found


nginx

デバッグの基礎

すべてのプログラマー――そう、プロでさえも――はバグのあるコードを書いてしまいます。初心者とエキスパートの違いは、ミスを犯すかどうかではなく、どれだけ早くそのミスを見つけて修正できるかにあります。このレッスンでは、毎日役立つデバッグのスキルを学びます。


1. 3種類のエラー

(1) 1.1 コンパイル時のエラー

これらは、プログラムが実行される前にコンパイラによって検出されます。

CPP
int x = 5
cout << x << endl; // ❌ Missing semicolon!

表示内容: コンパイラは、ファイル名と行番号を含むエラーメッセージを出力します。

解決方法: エラーメッセージを注意深く読みましょう。通常、問題の具体的な箇所や、本来どのような動作が期待されているかが明記されています。

(2) 1.2 実行時エラー

これらはプログラムの実行中に発生します。プログラムがクラッシュしたり、予期しない動作をしたりする可能性があります。

CPP
int arr[5] = {1,2,3,4,5};
cout << arr[100] << endl; // ❌ Array index out of bounds
int x = 10 / 0; // ❌ Division by zero

表示される内容: クラッシュ、「セグメンテーションフォールト」、または不正な出力。

解決方法: コードを逐一確認してください。配列の範囲外へのアクセス、ゼロ除算、およびNULLポインタのチェックを行ってください。

(3) 1.3 論理的誤り

プログラムはクラッシュすることなく動作しますが、間違った結果を出力してしまいます。こうした不具合は、最も発見が難しいものです。

CPP
// This should convert Celsius to Fahrenheit
double celsius = 100;
double fahrenheit = celsius * 9/5 + 32; // ✅ Correct: 212
double wrong = celsius * 9/5 - 32; // ❌ Wrong: 148

表示内容: プログラムは「動作」はするものの、間違った答えを出します。

解決方法: ここでデバッグ技術が真価を発揮します。



2. cout によるデバッグ手法

最も簡単なデバッグ手法:すべてを出力する

CPP
#include iostream

int factorial(int n) {
 int result = 1;
 for (int i = 1; i <= n; i++) {
 result *= i;
 std::cout << "[DEBUG] i=" << i << ", result=" << result << std::endl;
 }
 return result;
}

int main() {
 std::cout << factorial(5) << std::endl;
 return 0;
}

出力:

TEXT
[DEBUG] i=1, result=1
[DEBUG] i=2, result=2
[DEBUG] i=3, result=6
[DEBUG] i=4, result=24
[DEBUG] i=5, result=120
120
💡 ヒント: デバッグ出力には [DEBUG] というプレフィックスを付けておくと、後で簡単に見つけ出して削除できます。本番環境のコードにデバッグ出力を残したままにしないでください。



3. IDEのデバッガの使用

VS Codeのデバッガーでは、以下の操作が可能です:

  1. ブレークポイントを設定する — 行番号をクリックすると、その行で実行が一時停止します
  2. ステップオーバー — 1行ずつ実行する
  3. Step into — 関数に入り、内部で何が起きているかを確認する
  4. 変数の監視 — 値がリアルタイムでどのように変化するかを確認する

(1) VS Code でのデバッガーの設定

  1. C/C++ Extension Pack(デバッグツールを含む)をインストールします。
  2. .cpp ファイルを開きます
  3. F5 を押してデバッグを開始します
  4. 「C++ (GDB/LLDB)」環境を選択します
  5. 行番号をクリックしてブレークポイントを設定します
  6. F10 を押してコードを順に実行する


4. コンパイラの警告

警告はエラーではありませんが、コンパイラが「これは怪しい」と伝えているものです。警告はエラーとして扱うようにしてください。

CPP
// Compile with: g++ -Wall -Wextra -Werror program.cpp
フラグ 効果
-Wall 最も一般的な警告を有効にする
-Wextra 追加の警告を有効にする
-Werror すべての警告をエラーとして扱う

(1) ▶ サンプル:1:バグを見つけよう(難易度 ⭐⭐)

CPP
#include iostream

int main() {
 int x; // Bug 1: uninitialized variable
 std::cout << x; // Output is unpredictable!
 
 int arr[5];
 arr[5] = 10; // Bug 2: array out of bounds
 
 for (int i = 0; i <= 5; i++) { // Bug 3: should be i < 5
 arr[i] = i;
 }
 
 return 0;
}
▶ 試してみよう
💡 ヒント: -Wall -Wextra -Werror を使ってコンパイルすると、上記の3つのバグをすべて検出できます!


▶ サンプル 1: debugging basicsデモ (難易度 ⭐)

CPP
#include <iostream>

int main() {
 // debugging basicsの
 std::cout << "debugging basicsをびましょう!" << std::endl;
 return 0;
}
▶ 試してみよう

❓ よくある質問

Q プログラムは正常にコンパイルされるのに、実行すると何も出力されないのはなぜですか?
A 2つの可能性があります:① Windowsの場合、.exeファイルをダブルクリックするとターミナルが開きますが、すぐに閉じてしまいます。その場合は、代わりにCMDやPowerShellから実行してください。② プログラムが無限ループに陥っています。Ctrl+Cを押して終了させてください。
Q VS Codeのデバッガーはどのように設定すればよいですか?
A F5キーを押して、「C++ (GDB/LLDB)」を選択してください。すると、VS Codeがlaunch.jsonの設定ファイルを自動生成します。gdbがインストールされていること、およびプログラムのパスが正しいことを確認してください。
Q なぜ cout のデバッグ出力の順序が乱れているのですか?
A これはバッファリングの問題です。std::endl(フラッシュを行う)または std::flush を使用して、即時出力を強制してください。

📖 まとめ


📝 練習問題

  1. 初心者(難易度 ⭐): 以下のバグのあるプログラムを修正してください(5つのバグが含まれています):
CPP
#include iostream

int main() {
int x
cout << "Enter a number: ";
cin >> x
if (x = 5) {
std::cout << "You entered 5" << std::endl;
}
int arr[3] = {1,2,3};
std::cout << arr[3] << std::endl;
return 0
}
  1. 中級(難易度 ⭐⭐): 各種類のエラー(コンパイル時エラー、実行時エラー、論理エラー)を意図的に含めたプログラムを作成してください。その後、それらを一つずつ修正し、どのような変更を加えたかを記録してください。

  2. 上級(難易度 ⭐⭐⭐): 再帰関数を実装し、VS Codeのデバッガーを使用して、各再帰呼び出しをステップ実行してください。各レベルにおけるコールスタックの変化と変数の値を確認してください。デバッガーのスクリーンショットを撮影してください。

Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%