не удается получить доступ к памяти при обращении к указателю на структуру GDB ошибка

#c #gdb

#c #gdb

Вопрос:

Я запустил gdb, так как мой код показывает ошибку segfault. Я понимаю, что код, который выдает ошибку

 210         if (colour_s->colorlist.colorlist_id == 1)
(gdb) print colour_s
$1 = (car_colour_list_t_slot *) 0x21
(gdb) print colorlist
$2 = (car_colour_list_t *) 0x12d1a80
(gdb) print colour_s->colorlist
Cannot access memory at address 0x21

typedef struct {
    int colorlist_id;
} car_colour_list_t;


typedef struct _car_colour_list_t_slot {
    car_colour_list_t colorlist;
    struct _car_colour_list_t_slot *next, *prev;
} car_colour_list_t_slot;


car_colour_list_t_slot *colour_s;
colour_s = (car_colour_list_t_slot *)malloc(sizeof(car_colour_list_t_slot));
car_colour_list_t *colorlist;
colorlist = (car_colour_list_t *)malloc(sizeof(car_colour_list_t));
  

Я уже назначил этим указателям память, но когда я попытался напечатать color_s-> colorlist, это не удается (невозможно получить доступ к памяти по адресу 0x21)

Кто-нибудь может понять, почему это происходит, хотя я уже назначил память каждому пойтнеру?

Спасибо

Комментарии:

1. Вы, скорее всего color_s , прямо или косвенно перезаписываете где-то еще в своем коде.

2. Я назначаю его в одной функции, освобождаю указатель color_s и, используя сокет, это значение переходит к другим функциям (так что с этим значением произошло много чего). Мне просто нужно «отменить» это значение в моей функции.

3. Мы не можем догадаться, что вы делаете неправильно. Строки, которые вы показываете, в порядке. Итак, ваша ошибка в другом месте.

4. @Mat: дело в том, что я не использую этот указатель color_s на структуру в своей функции. Возможно, она ранее использовалась другой функцией (которая находится на удаленном сервере, возможно, она не освобождена или что-то в этом роде). Как я могу затем снова использовать этот указатель на эту структуру? Я попытался установить для этого указателя значение NULL, но все равно не помогает

5. Выведите значение color_s %p помощью спецификатора printf) сразу после его изменения, перекомпилируйте и повторно запустите свой код. Если значение, напечатанное gdb при segfault, не совпадает, то вы будете на 100% уверены, что вы изменяете эту переменную где -то в своем коде, прямо или косвенно.

Ответ №1:

colour_s Указатель определенно недействителен.В этом нет никаких сомнений. GDB просто информирует вас об этом факте. (Любой указатель вблизи 0x0 недопустим, и любой указатель с остатком по модулю 4 недопустим для вашей структуры.) malloc Функция никогда не вернет 0x21.

Есть много способов, которыми ваша программа может это сделать. Они сводятся к двум основным типам ошибок в вашей программе:

  • colour_s не был инициализирован.
  • colour_s был инициализирован, но он был случайно перезаписан ошибкой в другой части вашего кода.
  • ошибка в GDB или вашем компиляторе (не стоит учитывать)

Запустите свою программу с помощью Valgrind или установите контрольную точку включенной colour_s . Это поможет вам обнаружить, где ошибка в вашем коде.

В качестве альтернативного упражнения посмотрите, сможете ли вы найти ошибку, просто прочитав свой код, не запуская его. Прочитайте внимательно. Такого рода упражнения сделают вас лучшим программистом.

Комментарии:

1. Я уже назначаю память указателю, и я уверен, что в моем коде я вообще не назначал эту переменную..

2. @heike: Если вы уверены, что он инициализирован, то единственной другой возможностью является то, что ваша программа изменяет значение после его инициализации. Это может произойти через указатели на несвязанные переменные, если указатели используются неправильно. Это распространенный тип ошибки в C. Как я уже сказал, установите контрольную точку или запустите Valgrind.