Ошибка сегментации в доступе к легитимному адресу памяти
У меня странный сценарий 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
(который будет обращаться к висячему указателю), вы получите ошибку сегментации.