Вы передаете заголовок списка по значению, поэтому функция append
не может обновить указатель в пространстве вызывающего абонента, который имеет одно и то же имя head
. Аргумент head
в append
является отдельной переменной от локальной переменной head
в main
.
Вы должны либо передать указатель на головной узел, чтобы append
мог изменить его:
void append(node_t **headp, int data) { ...
Или вернуть вызывающему, возможно, измененный головной узел, который сохранит его обратно в свою собственную переменную:
node_t *append(node_t *head, int data) { ...
В обоих случаях рекомендуется сигнализировать об ошибке выделения памяти в звонящий. Вернуть код ошибки в первом подходе легко, в то время как возврат нулевого указателя во втором подходе может работать, если вызывающая сторона не сохраняет возвращаемое значение непосредственно в своей переменной head
, как в случае сбоя предыдущего значения будет потеряно.
Вот модифицированная версия с первым подходом:
#include <stdio.h>
#include <stdlib.h>
typedef struct node node_t;
struct node {
int data;
node_t *next;
};
// append a new node to the list, return 0 for success, -1 for allocation failure
int append(node_t **headp, int data) {
node_t *node = (node_t *)malloc(sizeof(node_t *));
if (node == NULL)
return -1;
node->data = data;
node->next = NULL;
if (*headp == NULL) {
*headp = node;
} else {
node_t *current = *headp;
while (current->next != NULL) {
current = current->next;
}
current->next = node;
}
return 0;
}
int main(void) {
node_t *head = NULL;
if (append(&head, 4) || append(&head, 6))
printf("node allocation error\n");
printList(head);
// should free the list
return 0;
}