В первом коде newnode
и start
оба начинают указывать на тот же node
, который вы выделили.Затем вы устанавливаете newnode->next = NULL;
, так что для start->next
также устанавливается NULL
.
Затем вы делаете:
newnode = newnode->next;
newnode = (struct node*)malloc(sizeof(struct node));
, так что newnode
теперь указывает на другой узел, ноstart
по-прежнему указывает на исходный узел.Так что start->next
все еще NULL
.Затем вы делаете:
start = start->next;
Это устанавливает start
в NULL
, поэтому попытка печати start->data
недопустима, поскольку вы не можете разыменовать нулевой указатель.
Первыйприсваивание перед malloc()
бессмысленно, потому что вы немедленно заменяете переменную чем-то другим.Полагаю, вы подумали, что при первом переназначении newnode
вызов malloc()
обновит и newnode
, и newnode->next
, поскольку вы объявили их эквивалентными.Но это не то, как работают назначения - все, что он делает, это копирует значение newnode->next
в newnode
, он не связывает эти два места вместе.
Ваша вторая версия получает это право, присваивая newnode->next
скорее newnode
.Это также присваивает start->next
, потому что newnode
и start
изначально указывают на одну и ту же структуру.Затем вы назначаете
newnode = newnode->next;
Это обновляет newnode
, но start
все еще в порядке и указывает на первый узел.Когда вы затем делаете
start = start->next;
, он обновляет start
, чтобы указывать также на второй узел.В этом случае допустимо start->data
, оно содержит то же, что вы присвоили newnode->data
несколькими строками ранее.