VC++デバック
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
Visual C++のデバック編です
Visual C++のデバック機能は非常に優秀で使いこなせば
大抵のバグの箇所を発見することができます
特にC/C++言語では直接変数のアドレスを(ポインタ変数と...
(他の言語にも参照というポインタに近い概念はある)
デバックするときは変数の値のチェックやアドレスのチェック...
まず、空のプロジェクトから
テスト用にmain.cppを作ります
デバックモードならばアドレスとかの関係も簡単に見れるので
今回はswap関数の例にしておきます
#include <stdio.h>
// 値入れ替え関数(駄目な例)
void swap1(int a,int b)
{
int tmp = a;
a = b;
b = tmp;
}
// 値入れ替え関数(OKな例)
void swap2(int* a,int* b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
int main()
{
int a = 5;
int b = 10;
printf("a = %d,b = %d\n",a,b);
swap1(a,b);
printf("a = %d,b = %d\n",a,b);
swap2(&a,&b);
printf("a = %d,b = %d\n",a,b);
}
先に実行結果は、次のようになります
swap1関数では変数a,bの値が変わっていませんが
swap2関数では変数a,bの値が無事入れ替わっています
アドレスの概念の復習がてら、デバックで見ていきましょう
&ref(debug13.GIF);
デバック起動するときは
Debugモードにしておきます
Releaseモードだと正しくデバックできません
&ref(debug.GIF);
次にソースコードの左枠の部分を左クリックします
すると赤点(ブレークポイント)が打たれます
デバック起動時、このブレークポイントのところで処理が止ま...
&ref(debug1.GIF);
それでは、デバック起動してみます
デバック起動をするには、
デバック→デバック開始を選ぶか、もしくはF5キーを押してく...
&ref(debug2.GIF);
すると、赤点(ブレークポイント)を打ったところで処理が止...
&ref(debug3.GIF);
呼び出し履歴のウィンドウはどの関数から呼ばれたかの履歴を...
自動変数は、今止まっている個所での変数の値をチェックする...
ない場合は、デバック→ウィンドウからそれぞれ出すことができ...
&ref(debug4.GIF);
デバックの進行方法ですが、主に次の5つです
・進行(F5キー):次のデバックポイントまで移ります
・デバックの中止(Shift + F5キー):デバックを中止します
・ステップイン(F11キー):一行進みます、関数の行の場合、...
・ステップオーバー(F10キー):一行進みます、関数の行の場合...
・ステップアウト(Shift + F11キー):関数の中に入っている...
&ref(debug5.GIF);
試しに、今の状態からF10キーを押します(ステップオーバー)
すると、aに5が代入され、
自動変数のaの値が5になっていることが確認できます
また、変数bが宣言されたのでbも自動変数の欄に登場します
bはまだ初期化されていないのでゴミが入っています
このように、自動変数のウィンドウは現時点で有効な変数のみ...
&ref(debug6.GIF);
とりあえず、
swap1までF10キーを押します(ステップオーバー)
&ref(debug7.GIF);
変数aとbのアドレスを見たいので
タブ切り替えでウォッチ式のウィンドウを出します
(自動変数のウィンドウでは見れない)
&ref(debug8.GIF);
ウォッチ式がない場合はデバック→ウィンドウ→ウォッチ1から...
番号はあまり関係ありません
&ref(debug9.GIF);
ウォッチ式の欄で次のように
左クリックして、入力してエンターキーを押します
&ref(debug10.GIF);
bも同様に行うと、aとbのアドレスは次のようになります
&ref(debug11.GIF);
この値は人によって違うと思います
私の場合は
aのアドレスは0x0012ff60
bのアドレスは0x0012ff54
になりました
このアドレスはあとでチェックするのでメモって置いてください
それではF11キーを押して(ステップイン)、swap1関数の中身...
&ref(debug12.GIF);
ここでいくつか見てほしい部分があります
まず、呼び出し履歴の欄です
swap1が追加されています
この下にmain関数の記述が書かれているので
このswap1はmain関数から呼び出されたものとわかります
プログラムが複雑になってきてバグが発生すると
どの関数から呼ばれてバグが発生したのか、
また、その時の変数の値などがバグの原因を突き止めるため大...
また、変数のアドレスを見てください
私の場合は
aのアドレスは0x0012fe7c
bのアドレスは0x0012fe80
となりましたが
先ほどのmain関数の変数a,bのアドレスと異なるはずです
試しにa,bのウォッチ式を追加します
&ref(debug14.GIF);
swap1関数の変数(引数)a,bにデータは確かにそれぞれコピー...
main関数の変数a,bのアドレスとswap1関数内の変数(引数)a,b...
main関数の変数a,bに影響を与えません
つまり、swap1は無駄な処理であることがこれでわかったはずです
では、Shift+F11を押して(ステップアウト)、swap1関数を抜...
&ref(debug15.GIF);
デバック起動中にもブレークポイントを打つことができます
試しに、次の箇所にブレークポイントを打ってみましょう
&ref(debug16.jpg);
F5を押してswap2関数に行きます
ここでswap関数には、main関数の変数aとbのアドレスを引数と...
さらにF5を押して、swap2関数に入ると次のようになります
&ref(debug17.GIF);
ここでswap2関数のポインタ変数(引数)a,bの値にはmain関数...
確認してみてください
私の場合は
aの値は0x0012ff60
bの値は0x0012ff54
となり、main関数の変数a,bのアドレスと一致しました
やっていることはアドレスの値をコピーしているにすぎないわ...
ポインタ変数はアドレスを値として格納する変数なのでアドレ...
次にウォッチ式に*a,*bの式を追加します
&ref(debug18.GIF);
*(アドレス)
は間接参照演算子とよばれ、
アドレスの指す先の値にアクセス(参照)することができます
もちろん、swap2関数のポインタ変数(引数)a,bの値はmain関...
その先の指すものは、main関数の変数a,bの値です
なのでswap2関数で*a,*bの値の入れ替えを行うことは直接main...
この項目を通してデバックのやり方と、
アドレスの概念が身に着いたと思います
慣れてくるとプログラムが落ちたときなど
デバック起動でバグの原因を究明し、
バグをなくせるようになると思います
積極的に使っていきましょう
|(^ω^)やったお|3|
|何これwww意味不すぎwww|0|
|。(`ω´#)。あぁん?最近、だらしねぇな|0|
終了行:
Visual C++のデバック編です
Visual C++のデバック機能は非常に優秀で使いこなせば
大抵のバグの箇所を発見することができます
特にC/C++言語では直接変数のアドレスを(ポインタ変数と...
(他の言語にも参照というポインタに近い概念はある)
デバックするときは変数の値のチェックやアドレスのチェック...
まず、空のプロジェクトから
テスト用にmain.cppを作ります
デバックモードならばアドレスとかの関係も簡単に見れるので
今回はswap関数の例にしておきます
#include <stdio.h>
// 値入れ替え関数(駄目な例)
void swap1(int a,int b)
{
int tmp = a;
a = b;
b = tmp;
}
// 値入れ替え関数(OKな例)
void swap2(int* a,int* b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
int main()
{
int a = 5;
int b = 10;
printf("a = %d,b = %d\n",a,b);
swap1(a,b);
printf("a = %d,b = %d\n",a,b);
swap2(&a,&b);
printf("a = %d,b = %d\n",a,b);
}
先に実行結果は、次のようになります
swap1関数では変数a,bの値が変わっていませんが
swap2関数では変数a,bの値が無事入れ替わっています
アドレスの概念の復習がてら、デバックで見ていきましょう
&ref(debug13.GIF);
デバック起動するときは
Debugモードにしておきます
Releaseモードだと正しくデバックできません
&ref(debug.GIF);
次にソースコードの左枠の部分を左クリックします
すると赤点(ブレークポイント)が打たれます
デバック起動時、このブレークポイントのところで処理が止ま...
&ref(debug1.GIF);
それでは、デバック起動してみます
デバック起動をするには、
デバック→デバック開始を選ぶか、もしくはF5キーを押してく...
&ref(debug2.GIF);
すると、赤点(ブレークポイント)を打ったところで処理が止...
&ref(debug3.GIF);
呼び出し履歴のウィンドウはどの関数から呼ばれたかの履歴を...
自動変数は、今止まっている個所での変数の値をチェックする...
ない場合は、デバック→ウィンドウからそれぞれ出すことができ...
&ref(debug4.GIF);
デバックの進行方法ですが、主に次の5つです
・進行(F5キー):次のデバックポイントまで移ります
・デバックの中止(Shift + F5キー):デバックを中止します
・ステップイン(F11キー):一行進みます、関数の行の場合、...
・ステップオーバー(F10キー):一行進みます、関数の行の場合...
・ステップアウト(Shift + F11キー):関数の中に入っている...
&ref(debug5.GIF);
試しに、今の状態からF10キーを押します(ステップオーバー)
すると、aに5が代入され、
自動変数のaの値が5になっていることが確認できます
また、変数bが宣言されたのでbも自動変数の欄に登場します
bはまだ初期化されていないのでゴミが入っています
このように、自動変数のウィンドウは現時点で有効な変数のみ...
&ref(debug6.GIF);
とりあえず、
swap1までF10キーを押します(ステップオーバー)
&ref(debug7.GIF);
変数aとbのアドレスを見たいので
タブ切り替えでウォッチ式のウィンドウを出します
(自動変数のウィンドウでは見れない)
&ref(debug8.GIF);
ウォッチ式がない場合はデバック→ウィンドウ→ウォッチ1から...
番号はあまり関係ありません
&ref(debug9.GIF);
ウォッチ式の欄で次のように
左クリックして、入力してエンターキーを押します
&ref(debug10.GIF);
bも同様に行うと、aとbのアドレスは次のようになります
&ref(debug11.GIF);
この値は人によって違うと思います
私の場合は
aのアドレスは0x0012ff60
bのアドレスは0x0012ff54
になりました
このアドレスはあとでチェックするのでメモって置いてください
それではF11キーを押して(ステップイン)、swap1関数の中身...
&ref(debug12.GIF);
ここでいくつか見てほしい部分があります
まず、呼び出し履歴の欄です
swap1が追加されています
この下にmain関数の記述が書かれているので
このswap1はmain関数から呼び出されたものとわかります
プログラムが複雑になってきてバグが発生すると
どの関数から呼ばれてバグが発生したのか、
また、その時の変数の値などがバグの原因を突き止めるため大...
また、変数のアドレスを見てください
私の場合は
aのアドレスは0x0012fe7c
bのアドレスは0x0012fe80
となりましたが
先ほどのmain関数の変数a,bのアドレスと異なるはずです
試しにa,bのウォッチ式を追加します
&ref(debug14.GIF);
swap1関数の変数(引数)a,bにデータは確かにそれぞれコピー...
main関数の変数a,bのアドレスとswap1関数内の変数(引数)a,b...
main関数の変数a,bに影響を与えません
つまり、swap1は無駄な処理であることがこれでわかったはずです
では、Shift+F11を押して(ステップアウト)、swap1関数を抜...
&ref(debug15.GIF);
デバック起動中にもブレークポイントを打つことができます
試しに、次の箇所にブレークポイントを打ってみましょう
&ref(debug16.jpg);
F5を押してswap2関数に行きます
ここでswap関数には、main関数の変数aとbのアドレスを引数と...
さらにF5を押して、swap2関数に入ると次のようになります
&ref(debug17.GIF);
ここでswap2関数のポインタ変数(引数)a,bの値にはmain関数...
確認してみてください
私の場合は
aの値は0x0012ff60
bの値は0x0012ff54
となり、main関数の変数a,bのアドレスと一致しました
やっていることはアドレスの値をコピーしているにすぎないわ...
ポインタ変数はアドレスを値として格納する変数なのでアドレ...
次にウォッチ式に*a,*bの式を追加します
&ref(debug18.GIF);
*(アドレス)
は間接参照演算子とよばれ、
アドレスの指す先の値にアクセス(参照)することができます
もちろん、swap2関数のポインタ変数(引数)a,bの値はmain関...
その先の指すものは、main関数の変数a,bの値です
なのでswap2関数で*a,*bの値の入れ替えを行うことは直接main...
この項目を通してデバックのやり方と、
アドレスの概念が身に着いたと思います
慣れてくるとプログラムが落ちたときなど
デバック起動でバグの原因を究明し、
バグをなくせるようになると思います
積極的に使っていきましょう
|(^ω^)やったお|3|
|何これwww意味不すぎwww|0|
|。(`ω´#)。あぁん?最近、だらしねぇな|0|
ページ名: