このページの内容 |
---|
デバッグとは? |
デバッグの基本は 『出力』 |
Win32アプリケーションの場合は? |
ありがたいスポンサー様 |
---|
All About ソフトウエアエンジニア |
ネットで8%割引!自動車保険はアメリカンホーム・ダイレクト |
人生の「チャンス」と「ピンチ」にモビット! |
保険料が一生上がらない、保険料最大50%割引の一生涯の医療保険! |
プロジェクトをビルドできたからといって、その実行ファイルが完全であるとは言えません。実行できたところで、思い通りに動かなかったり、メモリリークが起こってしまうことはよくあることです。実際、プログラミングになれてくると、コンパイルが通って1段落、「さぁ、デバッグするぞ…」という気分になります。
ここでは、デバッグの方法を コンソールアプリケーション の例で説明します。
アプリケーションで何が起こっているかを追跡するためには、アプリケーションの中の情報を出力するのが一般的です。例えば、次のような階乗を計算する関数を定義したソースを考えてみましょう。
#include <stdio.h> int calc_kaijo( int i) { // 正しくは i == 1 if( i = 1) { return 1; } else { // 正しくは calc_kaijo(i-1); return i * calc_kaijo(i) ; } } void main() { // 5の階乗を計算する printf( "result : %d\n", calc_kaijo( 5)) ; }
calc_kaijo関数では、再帰呼び出しを使って階乗を計算します。例えば 『5の階乗 = 5 * 4 * 3 * 2 * 1』 です。
このソースはコンパイルできますが、2つの重大なバグを含んでいます。プログラマのいとしたとおりに動いてくれないからには、バグを含んでいるといえます。本当なら、『result : 120』と出力して欲しいのに、『result : 1』 と出力されてしまいます。
何度、プログラムを見直してもわからない場合は、次のように 『変数の値を出力してみる』 ということが有用です。
int calc_kaijo( int i) { if( i = 1) // 正しくは i == 1 { printf("i は 1 らしい\n"); return 1; } else { printf("i : %d\n", i); // 正しくは calc_kaijo(i-1); return i * calc_kaijo(i) ; } }
これで、calc_kaijo関数が呼ばれるたびに、iの値をコンソールに出力するようになります。プログラムをこのように改造して実行してみると、次のように出力されました。
i は 1 らしいresult : 1
出力を見れば、バグがどこに潜んでいるかの見当がつきます。main関数でcalc_kaijo関数を、引数i = 5として呼び出しているのに、最初のif文が 真(true) と評価されているようです。
ifの周辺を注意深く見れば、ifの評価部分が間違っていることに気付くでしょう。修正してビルドして実行すると、次のように表示されて無限ループに突入してしまいました。
i = 5 i = 5 i = 5 : :
毎回、i = 5でcalc_kaijo関数が呼ばれてしまっているようです。再帰呼び出し部分に当たりをつけて注意深く見れば、2つめのバグにも気付くはずです。
このように、プログラムの各部分でいろいろな情報を出力することで、変数の値や、if文の分岐がどのようになっているかを知ることができ、バグのありかを推測できるようになります。もちろん、この方法で全てのバグを取れるわけではありません。しかし、ただ全体を眺めてバグのありかを模索するよりかは、はるかにすばらしい手法でしょう。
さて、次のページでは Win32 アプリケーションでデバッグ処理を行うときのポイントを解説します。Win32アプリケーションでは、printf関数を使ってもどこにも出力できません。どのようにやるかは次のページをご覧ください。