デバッガの使い方4

本来正常実行されるはずが、エラーメッセージが出る

例えば、何かあらかじめデータをセットしてからじゃないと呼び出しちゃいけないメソッドを持つようなクラス設計をした場合、値をセットしてからそのメソッドを呼び出すまで、間に色々処理が入っていると、自分の思ったとおり動かないことがよくある(GofのCommandパターンによく起こりやすい)。例えば、以下のようなコード(わざとらしいけど・・)。


01 struct S
02 {
03 S() : m_p(NULL) {}
04 void set(const char* p){ m_p = p; }
05
06 void func() const
07 {
08 if( m_p ) cout << "S::func " << m_p << endl;
09 else cout << "Error, m_p is NULL" << endl;
10 }
11 private:
12 const char* m_p;
13 };
14
15 void func(S& s)
16 {
17 s.set(NULL);
18 }
19
20 int main()
21 {
22 char* p = "hoge";
23
24 S s;
25 s.set(p);
26 func(s);
27 s.func();
28
29 return 0;
30 }

実行すると、"Error, m_p is NULL" と出力される。25行目でちゃんと有効な値をセットしたつもりになっていたら、どうしてか非常に不思議だ(もちろんこの例ではすぐ原因はわかるが)。こんな時はこのメンバ変数m_pにNULLがセットされる処理を探す必要がある。なので、4行目にブレークポイント(F9)をセットして、デバッグ実行(F5)して待ち構え、引数pの値を変数ウィンドウでチェックする。

1回目:文字列"hoge"のアドレス値
2回目:NULL

この2回目のNULLの時に、どの関数から呼ばれているかをコールスタックから調査すればわかる。

今回の説明内容まとめ