Ошибка сегментации в доступе к легитимному адресу памяти

У меня странный сценарий segmentation fault при попытке получить данные в допустимом указателе. У меня есть INTEGER указатель с именем p и всякий раз, когда я пытаюсь получить данные в p с помощью *pЯ получаю ошибку сегментации.

Я пытался выяснить проблему, используя GDB, Пока в GDBэталон памяти еще кидает SIGSEGV хотя я могу получить правильные данные, используя print *p

Мой фрагмент кода выглядит следующим образом:

int *p = (int*)malloc(sizeof(int));
// some other codes
printf("%d\n", *p);

Наверняка p не является NULL, Потому что я проверил на NULL перед печатью. Но я не могу быть уверен, что он указывает на какое-то неверное местоположение. Потому что код в середине слишком большой, чтобы узнать. Есть ли способ проверить, указывает ли он на случайные места?

Чтобы убедиться, что он не указывает на некоторые случайные места, я напечатал адрес в p сразу после malloc и до printf утверждение и они кажутся одинаковыми. Так что я думаю, что адрес не случайный. Также GDB print дает мне правильные данные, которые я ожидаю.

1 ответ

Я напечатал адрес в p сразу после malloc и перед оператором printf, и они кажутся одинаковыми.

Насколько сложно быть абсолютно уверенным, что они одинаковы?

Серьезно, вам нужен рациональный подход вместо того, чтобы говорить "помогите, у меня есть тонны кода, и я понятия не имею, где может быть проблема" - никто не может помочь вам дать эту информацию.

Итак, какие рациональные вещи вы могли бы сделать?

Вы можете начать вставлять printf("ZZZZ %s: %d: %d\n", __FILE__, __LINE__, *p); везде Тот printf не будет сбой сразу после malloc, но в какой-то момент так и будет. Поздравляем: вы только что сузили проблему.

Более быстрый подход может состоять в том, чтобы запустить вашу программу под Valgrind или AddressSanitizer: эти инструменты часто приводят вас прямо к проблеме.

Что касается проблемы на самом деле, я подозреваю, что ваш malloc фактически выделяет несколько мегабайт данных, а не 4 байта, которые вы показали, и для такой большой порции вызовет glibc mmap, если ты free эти данные позже, Glibc будет munmap кусок, и сделать память недоступной. В следующий раз, когда вы попытаетесь распечатать *p (который будет обращаться к висячему указателю), вы получите ошибку сегментации.

Другие вопросы по тегам