という名前の構造体へのポインター内にポインターがある C コードをデバッグしていますboard
。ボードを印刷している機能があります:
static void board_print(board *b){
int i,j;
char data;
for (i = 0; i < size; i++) {
for (j = 0; j < size; j++) {
data = b->data[i * size + j];
if(data){
printf("X ");
}else{
printf("O ");
}
}
printf("\n");
}
}
ここが奇妙な部分です。最初の for ループの先頭で最初にブレークポイントにヒットすると、すべて問題なく、データは正しく、すべてのポインターは次のように機能します。
次に、i と j を 0 にして初めてループに入りb->data[0]
ます。2 ステップ前のように、完全に有効なはずです。突然、ラインを踏むとすぐにdata = b->data[i * size + j];
、データ ポインターがヌル ポインターに変わります。この行を実行すると、(明らかに) 以下に示すように、不正なアクセス エラーが発生します。
その理由は何ですか?私は以前に C を使用したことがあり、それについてはかなり理解していますが、シングルスレッドの単純な C プログラムにステップインしているときに、ポインタ値が突然 null に変化するのを見たことはありません。Apple LLVM Compiler 4.1 を使用してコンパイルし、lldb を使用してデバッグしています。これは、XCode 4.5 のデフォルトです。
更新: gcc でコンパイルし、gdb でデバッグした場合と同じ動作が観察されました。私の側ではほぼ100%エラーですが、コードの何が問題なのかわかりません..
更新 #2: gcc/gdb でさらに奇妙なことに気付きました。行を実行する直前にdata = b->data[i * size + j];
、問題なくデバッガーからすべてにアクセスできます。その行を実行した直後は、b->data
ステップ実行の直前にアクセスした値を含め、完全にアクセスできません。
$4 = ...
デバッガーで正常に実行された行の後、その行をまたがりました。次に、上記のようにさまざまなアドレス指定エラーが発生しました。私は本当に何が起こっているのか分かりません...
更新 #3:非常に奇妙なことに気付きました。ここで、まず私が実装した修正を見てください。名前付きの変数をdata
完全に削除すると、これは問題なく動作し始めました。
ここで、更新 #2 でアップロードしたスクリーンショットをよく見てください。という名前のローカル変数に値を割り当てた直後に、そのアドレスdata
も変更されます。b->data
割り当ての副作用のように見えます。しかし、その背後にある理由が何であるかはわかりません。