Есть несколько проблем с вашим кодом:
Вы malloc
ing node1
, но вы нигде не устанавливаете значение.Это создает неопределенное поведение всякий раз, когда вы пытаетесь получить доступ к value
- вы можете аварийно завершить работу программы или получить ненужные данные, что, как правило, хуже, поскольку это приводит к тому, что другие части вашего кода ведут себя странно.
Вы не освобождаете динамически выделенную память.Хотя в вашем случае это не такая уж большая проблема, это говорит мне, что вы не знакомы с тем, как работает динамическое распределение (мое убеждение также усиливается первым пунктом в этом списке).Всякий раз, когда вы malloc
что-то, всегда free
это (в C ++ у вас есть new
и delete
) и (для предотвращения непредвиденного поведения) установите указатель на NULL
.
node2
не является указателем.*
в Node *node1, node2;
применяется только к первой переменной.Каждая последовательная переменная также нуждается в *
, в противном случае она будет размещена в стеке.
Из анализа вашего кода становится ясно, что вы хотите, чтобы node2
был указателем (в противном случае выне будет присваивать NULL
в качестве значения :)).В этом случае вы пытаетесь получить доступ к next
из node2
, но node2
инициализируется как NULL
:
int findLastNodeValue(Node* head){ // You are passing node2, which is NULL
while(head -> next != NULL){ // Can't access next of a NULL -> code breaks
head = head -> next;
}
return head -> value;
}
Как правило, выполните следующие действия:
Попробуйте использовать функцию, которая создает экземпляр вашего узла - поскольку это C
, у вас нет конструктора, я бы посоветовал написать функцию (или несколько, в зависимости от того, сколько функциональности вам нужно), который генерирует новый узел.Таким образом, вы гарантируете, что, по крайней мере, нет шансов не инициализировать узел
Например:
Node* createNode(int value) {
Node* node = (Node *)malloc(sizeof(Node));
if (!node) return NULL; // If malloc fails for some reason
node -> value = value;
node -> next = NULL;
return node;
}
Попробуйте использовать функцию, которая удаляет ваш узел -если есть шанс снова получить доступ к удаленной ссылке, установите для нее значение NULL
и соответственно обработайте значение NULL
Например:
void deleteNode(Node** node) {
if (!*node) return;
free(*node);
*node = NULL;
}
Обратите внимание, что приведенный выше код нене удаляйте ссылку на next
, так как мы хотим удалить только тот узел, который передаем функции.Если у вас есть previous
(в случае двойного связанного списка), вам сначала нужно получить доступ к узлу next
, установить его значение previous
равным NULL
, а затем удалить текущий узел.
Всякий раз, когда вы передаете указатель, всегда проверяет, равен ли этот указатель NULL
, прежде чем что-либо делать с данными, на которые он якобы ссылается.Комбинируя это с функцией создания узла с первой точки, вы можете быть уверены, что не передаете какой-то указатель Node
, который не был правильно инициализирован
Теперь о вашей функции в частностиЯ бы сделал следующее:
int findLastNodeValue(Node* head) {
if (!head) return -1; // We have a null reference, so there is nothing else to do here; exit accordingly and check the return value to see if the function call has been successful
while(head -> next != NULL) {
head = head -> next;
}
return head -> value;
}