Ваша проблема в том, что вы итерируете с сам указатель в appendNode
[1] .Это меняет адрес списка каждый раз, когда вы назначаете что-то на *ptr
, например,
*ptr = newnode;
...
*ptr = (*ptr)->link;
Каждый раз, когда *ptr
назначается, адрес списка меняется (как видно на appendNode
и main()
)
Ваши операции со списком верны, все, что вам нужно сделать, это использовать временный указатель для перебора списка (iter
ниже)
void appendNode (int data, struct node **ptr) {
struct node *newnode = malloc (sizeof *newnode),
*iter = *ptr;
if (!newnode) { /* VALIDATE every allocation */
perror ("malloc-newnode");
exit (EXIT_FAILURE);
}
newnode->data = data;
newnode->link = NULL;
if (iter == NULL) {
*ptr = newnode;
}
else {
while (iter->link != NULL) {
iter = iter->link;
}
iter->link = newnode;
}
}
( note использование разыменованного указателя, используемого с sizeof
для установки размера шрифта. Если вы используете разыменованный указатель для установки размера, вы устраняете любую ошибку при установкетребуется фактический тип. Кроме того, если вы выделяете - вы должны проверять - каждый раз)
С этим изменением (и следующим изменением на printList
)
void printList (struct node *node)
{
while (node != NULL)
{
printf(" %d ", node->data);
node = node->link;
}
putchar ('\n'); /* tidy up with newline */
}
Ваш список работаетпросто отлично, например
Пример использования / Вывод
$ ./bin/lllast2
23 45 32 11 98
сноски:
1. Хотя это и не ошибка, C обычно избегает использования camelCase
или MixedCase
имен переменных в пользу всех строчных букв при резервировании заглавные имена для использования с макросами и константами.Это вопрос стиля - так что это полностью зависит от вас, но если вы не будете следовать ему, то в некоторых кругах может произойти неправильное первое впечатление.