Отладка Xcode C изменяет значения указателей при пошаговом выполнении
Я отлаживаю 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 равны нулю, и b->data[0]
должно быть совершенно верно, так как оно было два шага назад. Внезапно, как только я перехожу на строку data = b->data[i * size + j];
, указатель данных превращается в нулевой указатель. Когда я выполняю строку, я (очевидно) получаю плохую ошибку доступа, как показано ниже:
В чем может быть причина? Я уже использовал C раньше, и я довольно хорошо его понимаю, но я никогда не видел, чтобы значение указателя внезапно менялось на null, когда вы входите в однопоточную простую программу C. Я использую Apple LLVM Compiler 4.1 для компиляции и lldb для отладки, которые это значения по умолчанию для XCode 4.5.
Update : такое же поведение наблюдается при компиляции с gcc и отладке с gdb. Почти стопроцентный аррор на моей стороне, но я понятия не имею, что не так с кодом..
Обновление #2: я заметил кое-что еще более странное на gcc/gdb сейчас. Непосредственно перед выполнением строки data = b->data[i * size + j];
, я могу получить доступ ко всему из отладчика без проблем. Сразу после выполнения этой строки я не могу получить доступ к b->data
полностью, включая значения, к которым я обратился непосредственно перед шагом:
После строки $4 = ...
, успешно выполненной в отладчике, я перешагнул через нее. Затем у меня есть различные ошибки адресации, как показано выше. Я действительно понятия не имею, что происходит...
Обновление #3: я заметил кое-что очень странное. Вот, сначала посмотрите на исправление, которое я реализовал. Этот начал работать без проблем, когда я избавился от переменной с именем data
полностью:
data
, также b->data
получает свой адрес изменен. Это выглядит как побочный эффект задания. Но я понятия не имею, что за этим кроется.1 ответ:
Очевидно, что что-то / кто-то изменяет свойство "данные" структуры платы.
Почему ? Я вижу только 3 причины:
Ваше приложение многопоточно, и другой поток обновляет указатель данных до NULL (что не ваш случай, вы используете только один поток, извините, не заметил).
Структура платы выделяется из стека, но содержание больше не является действительным... Например: возвращается указатель на локальную переменную, но переменная (структура) уничтожается (поскольку это локальная переменная) при возврате указателя...
Структура платы выделяется из кучи, затем освобождается, и, наконец, этот освобожденный указатель все еще используется : память кучи повреждена чем-то другим...
Мое предположение: второй пункт, который является частой ошибкой
Итак, простой вопрос : структура платы хранится в памяти кучи или стека ?