Protip на указатели отладки
Рисуем картинки. Сделайте прямоугольник для каждого экземпляра и стрелку из каждого ненулевого указателя. ВСЕГДА следуйте правилам, перечисленным ниже. Предполагая, что все управление памятью выполняется с malloc
и free
, нет никаких исключений из этих правил
- Каждый раз и только когда вы делаете
malloc
, вы должны нарисовать новую коробку.
- Каждый раз и только когда вы используете
free
, вы должны убирать (или просто скрещивать с X или чем-то) коробку.
- Каждый раз, когда вы используете
free
, уберите все стрелки из этого ящика.
- Каждый раз, когда вы назначаете указатель на значение, нулевое или ненулевое, удаляйте старую стрелку, если она существует.
- Каждый раз и только когда вы назначаете указатель на ненулевое значение, рисуйте стрелку.
Примечание. Для обычного вызова malloc
вы должны использовать оба правила 1, 4 и 5. Использование malloc
без учета указателя возврата означает утечку памяти.
Примечание 2: Важно! НЕ ДОЛЖНО убирать стрелку в поле, которое вы освобождаете, когда используете free
. Делайте это только когда вы специально назначаете указатель на ноль. Точно так же НЕ снимайте флажок при назначении указателя на ноль.
Примечание 3: Важно! Если вы освобождаете ящик, правило 3 гласит, что вы должны удалить все стрелки из этого ящика. НЕ снимайте коробки, на которые указывают стрелки.
Ваш вопрос
Учтите это:
ptr = ptr -> next;
ptr = malloc(sizeof(decks));
Первая строка не имеет никакого эффекта, поскольку вы немедленно переназначаете ptr
.
Вам нужно что-то вроде этого:
ptr -> next = malloc(sizeof(decks));
ptr = ptr -> next;
Другие замечания
Я бы рекомендовал использовать sizeof для переменной, а не для типа, например так: ptr->next = malloc(sizeof *(ptr->next))
В общем, это хорошая привычка. Возьми этот код:
int *x;
x = malloc(sizeof(int));
Теперь рассмотрим, хотите ли вы изменить тип переменной x
. Вам потребуется изменить аргумент на sizeof
при КАЖДОМ вызове malloc
. Использование x = malloc(sizeof *x)
полностью устраняет эту проблему.