#c #linked-list
#c #связанный список
Вопрос:
Я создаю программу связанного списка, которая использует несколько функций для упрощения добавления или удаления узлов из списка. Я считаю, что моя логика в порядке с выделением и добавлением нового узла, но я все еще получаю ошибку seg. Не могли бы вы просмотреть мою логику и объяснить, что вызывает ошибку seg? Я очень неопытен в связанных списках. Спасибо!
Это мои объявления функций
#define SIMPLELL_H
#include<stdio.h>
#include<stdlib.h>
typedef struct Node
{
int data;
struct Node *next;
}node_t;
node_t* head;
void printList();
void append(int num);
void addFront(int num);
void deleteList();
void removeNode(int num);
int length();
#endif
Это определения функций
void printList(){
// declare temp to traverse the LL and print each value
node_t *temporary = head;
while(temporary != NULL){
printf("%d, ", temporary->data);
temporary = temporary->next;
}
if (head == NULL){
printf("This list is empty.n");
}
}
void append(int num){
//declare temporary pointer to traverse LL
node_t *tmp = head;
node_t *prev = NULL;
//malloc the new node
node_t *new = malloc(sizeof(node_t));
if(head == NULL){
//initialize the new node
new->data = num;
new->next = NULL;
head->next = new;
}
else{
//initialize the new node
new->data = num;
new->next = NULL;
//loop to traverse to the last value in the node
while(tmp != NULL){
prev = tmp;
tmp = tmp->next;
}
prev->next = new;
}
}
void addFront(int num){
//allocate memory for new node and allocate local variable equal to head
node_t *new = malloc(sizeof(node_t));
new->data = num;
new->next = head;
head = new;
}
void deleteList(){
node_t *tmp = head;
node_t *prev = NULL;
while(tmp != NULL){
prev = tmp;
tmp = tmp->next
free(prev);
}
}
void removeNode(int num){
//temp is used to traverse the ll until I find the node with the value
//then the previous value is linked to the next value removing the middle value.
node_t *temp = head;
node_t *prev = NULL;
if(head == NULL){
printf("List is not initializedn");
return;
}
while(temp->data != num){
prev = temp;
temp = temp->next;
if (temp->data == num){
prev->next = temp->next;
free(prev);
}
else{
printf("Value is not in the listn");
return;
}
}
int length(){
int length = 0;
node_t *temp = head;
while (temp != NULL){
length = 1;
temp = temp->next;
}
return length;
}
Это функция драйвера, которую мне не нужно менять
#include "SimpleLL.h"
#include "SimpleLL.c"
int main()
{
/*head is a global variable*/
head = NULL;
int size =0;
removeNode(1);
append(2);
append(3);
addFront(1);
append(4);
printList();
size = length();
printf("size now %dn",size);
removeNode(8);
printList();
removeNode(1);
printList();
removeNode(4);
printList();
deleteList();
printList();
size = length();
printf("size after deletion %dn",size);
return 0;
}
Комментарии:
1.
/*head is a global variable*/
Это очень плохая идея.2. Рассмотрим, что происходит,
append
когда «список» пуст. Какое значениеprev
имеет?3. Это должно быть просто
NULL
правильно? В этом случае я должен использовать оператор if, чтобы указать, когдаhead/prev
значение равно NULL?4. Это помогло бы. Также обратите внимание, что
printList
это всегда будет печататься"This list is empty.n"
в конце. Это может быть не ожидаемое поведение.5. Итак, я отредактировал свою функцию добавления, чтобы включить этот оператор if, однако я все еще получаю ошибку seg. Я знаю, что эта ошибка seg возникает в функции добавления, однако я все еще не уверен, что является ее причиной. Я предполагаю, что это моя функция malloc, но я не уверен, почему это вызывает ошибку seg.
Ответ №1:
removeNode
не содержит теста для достижения конца списка. Поэтому, если значение не найдено в списке, оно разыменует нулевой указатель в конце и завершится сбоем.
Это будет иметь место в самом первом тесте, который пытается удалить узел, когда список пуст, а также для removeNode(8)
.
Ваша removeNode
функция также нуждается в free()
удаленном узле. В настоящее время он освобождает узел, который появился после удаленного, который все еще находится в списке и вызовет неопределенное поведение при последующем доступе к нему.
Комментарии:
1. Спасибо за быстрый ответ. Теперь я исправил это, но после этого моя функция все еще выдает ошибки. Я думаю, что есть проблема с моей функцией добавления узла, но я не уверен, что это такое. Я скоро обновлю свой пост
2. @Arock475: Вы не исправили это — теперь, что произойдет, если список не пуст, но нужного числа в нем нет? Как и в случае с
removeNode(8)
.3. Вы абсолютно правы, я об этом не подумал. Спасибо
4. @Arock475: Ваша
free()
ошибка неверна — см. Редактирование.5. Я думаю, что я исправил проблему с free(), а также исправил ее так, чтобы, если значения нет в связанном списке, оно правильно печатало сообщение об ошибке и завершало работу.