Я делаю переход от Java к обучению C для класса. Текущее упражнение - реализовать методы removeAtFront(), searchNode() и freeList() для LinkedList. Я понимаю теоретически, как это работает - я бы быстро это сделал на Java, я просто пытался часами и не понимаю, почему приведенный ниже код не работает.C связанный список searchNode/freeList методы (seg fault)
Метод удаления работает, создавая правильный измененный список, пока метод поиска не будет вызван ПОСЛЕ удаления узла. Затем генерируется раздельная ошибка 11. Свободный метод также всегда вызывает ошибку seg.
Я не прошу людей делать домашнее задание, но если бы я мог быть направлен в правильном направлении, это было бы очень признательно!
Данный узел * структура является:
typedef struct Node
{
char *word;
struct Node *next;
} Node;
Методы снаружи от основной() читать, как это:
void insertAtFront(Node **head, char * key)
{
Node *new = malloc(sizeof(Node));
if (!new) fatal("Malloc of new Node failed");
new->word = key;
new->next = *head;
*head = new;
}
void insertAtTail(Node **head, char * word)
{
if (!(*head)) insertAtFront(head, word);
else insertAtTail(&(*head)->next, word);
}
void removeAtFront(Node ** head)
{
Node *tmp = *head;
if (!tmp) return;
*head = tmp->next;
free(tmp->word);
free (tmp);
}
void removeNode(Node ** head, char * key)
{
Node *tmp = searchNode(*head, key);
if (tmp) removeAtFront (&tmp);
}
Node * searchNode (Node * head, char * key)
{
if (!head || (strcmp(head->word, key) == 0)) return head;
return searchNode(head->next, key);
}
void freeList( Node ** head)
{
if (!head) return;
if (&(*head)->next) freeList (&(*head)->next);
removeAtFront(head);
}
EDIT: Один из комментариев фиксированной моей проблемы с FreeList(), но другие запросили больше кода. Проблема с этим назначением заключается в том, что мне разрешено изменять методы insertAtTail(), removeAtFront(), remove(), search() и freeList(). Однако я опубликую основной метод. Я думаю, что значения слова правильно распределены внутри этого.
Node *searchNode(Node * head, char * key);
void insertAtFront(Node **head, char * key); // ALREADY WRITTEN FOR YOU
void insertAtTail(Node **head, char * key);
void removeAtFront(Node ** head);
void removeNode(Node **head, char * key);
void freeList(Node **head);
void printList(Node * head); // ALREADY WRITTEN FOR YOU
void fatal(char * msg); // ALREADY WRITTEN FOR YOU
#define BUFFER_CAP 20
int main()
{
Node *head = NULL;
while (1)
{
char option;
printf("\nChoose 'H'ead Insert, 'T'ail insert, 'R'emove, 'S'earch, F'ree, 'Q'uit ");
fflush(stdout);
int result = scanf(" %c%*[^\n]", &option); getchar(); // MAGIC BULLET TO CORRECTLY READ A SINGLE CHAR FROM STDIN
if (result <1) fatal("failure reading from stdin\n");
if (option == 'H')
{
char * word=malloc(BUFFER_CAP); // DONT ENTER ANY LONG WORDS!
printf("Enter a word to insertAtFront: ");
fflush(stdout);
char * result = fgets(word, BUFFER_CAP, stdin);
if (result==NULL) fatal("failure reading from stdin\n");
strtok(word,"\n"); // overwrites '\n' with '\0'
insertAtFront(&head, word); /* shallow copy string into list */
printList(head);
}
if (option == 'T')
{
char * word=malloc(BUFFER_CAP); // DONT ENTER ANY LONG WORDS!
printf("Enter a word to insertAtTail: ");
fflush(stdout);
char * result = fgets(word, BUFFER_CAP, stdin);
if (result==NULL) fatal("failure reading from stdin\n");
strtok(word,"\n"); // overwrites '\n' with '\0'
insertAtTail(&head, word); /* shallow copy string into list */
printList(head);
}
if (option == 'R')
{
char * word=malloc(BUFFER_CAP); // DONT ENTER ANY LONG WORDS!
printf("Enter a word to remove: ");
fflush(stdout);
char * result = fgets(word, BUFFER_CAP, stdin);
if (result==NULL) fatal("failure reading from stdin\n");
strtok(word,"\n"); // overwrites '\n' with '\0'
removeNode(&head, word);
printList(head);
free(word); // we were just using it for matching
}
if (option == 'S')
{
char * word=malloc(BUFFER_CAP); // DONT ENTER ANY LONG WORDS!
printf("Enter a word to find: ");
fflush(stdout);
char * result = fgets(word, BUFFER_CAP, stdin);
if (result==NULL) fatal("failure reading from stdin\n");
strtok(word,"\n"); // overwrites '\n' with '\0'
if (searchNode(head, word))
fprintf(stderr, "%s FOUND\n",word);
else
fprintf(stderr, "%s NOT FOUND\n",word);
printList(head);
free(word); // we were just using it for matching
}
if (option == 'F') // free the entire list (remember to set head to NULL)
{
freeList(&head);
printList(head);
}
else if (option == 'Q')
exit(0);
} // END WHILE
return 0;
}
Как отметили пару плакатов, у вас могут быть проблемы с распределением и освобождением Node :: word. Кто владеет этой памятью после создания узла? Кроме того, мне интересно об использовании. Можете ли вы показать нам тестовый код, который рушится? – SirPentor
Другая подозрительная вещь: 'if (& (head) -> next)' где условие всегда верно. Вероятно, 'if ((* head) -> next)' предназначалось. –
@ Антон Коваленко Да, я также считаю, что это должно быть '((* head) -> next)'. и '(& (* head) -> next)' is wrong –