Ваша проблема лежит здесь, в else
бите:
tail = malloc (sizeof (struct Node));
tail = tail->next;
tail->data = current->data;
tail->next = NULL;
Вы выделяете новый узел и устанавливаете tail
для указания на него (в первой строке). Тогда вы используете tail
, как будто это старый хвост. В частности, эта вторая строка даст вам мошеннический указатель (так как вы не инициализировали новый узел с действительными указателями), который, вероятно, вылетит в третьей строке, когда вы попытаетесь разыменовать его.
Вам нужно что-то вроде:
// First, set up the new node.
newList = malloc (sizeof (struct Node));
newList->data = current->data;
newList->next = NULL;
// Then, adjust the tail pointers.
tail->next = newList;
tail = newList;
На самом деле, оглядываясь на свой код, то, что вы вероятно намеревались, было:
tail->next = malloc (sizeof (struct Node)); // use tail->next, not tail.
tail = tail->next;
tail->data = current->data;
tail->next = NULL;
, который достигает того же результата.
Полагаю, я должен упомянуть, что вам действительно следует проверить возвращаемые значения из malloc
на случай, если вам не хватит памяти. Вы можете сделать это с чем-то вроде:
tail->next = malloc (sizeof (struct Node)); // use tail->next, not tail.
if (tail->next == NULL) {
// do something here for recovery.
return;
}
// Only continue here if the allocation worked.
tail = tail->next;
tail->data = current->data;
tail->next = NULL;
Без таких проверок вы получите сбой при исчерпании памяти.