我有一个使用列表的问题

I have a problem with a problem that uses lists

我对这段代码有疑问。我尝试使用 gdb 和 Valgrind 进行调试,但没有任何效果...

代码的目标是创建一个列表,只有当列表中已经没有具有相同字符串的现有节点时,才添加每个字符串。

这是代码:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

struct node {
    char *word; 
    struct node *next; 
}; 

void print_list(struct node *head) {
    while ((head) != NULL) {
        printf(" %s -> ", head->word); 
        head = (head->next);    
    }
}

// insert a new node in head
void add_n(struct node **head, char *str) {
    struct node *new; 
    new = malloc(sizeof(struct node)); 
    if (new == NULL) {
        printf("Not enough memory\n");
        exit(EXIT_FAILURE);
    }
    new->word = str; 
    new->next = NULL; 
    if ((*head) == NULL){
        (*head) = new;      
    }
    while ((*head)->next != NULL) {
        head = &(*head)->next;
    }
    (*head)->next = new;
}

// check if str is present in the list 
int find_string(struct node **head, char *str) {
    int found = 0; 
    while ((*head) != NULL) {
        int i = strcmp(str, (*head)->word);     //i=0 are the same 
        if (i == 0) {
            found = 1; 
            return found;       
        }
        head = &((*head)->next); 
    }
    return found; 
}

// insert a new string in the list only if is new
void insert(struct node **head, char *str) {
    if (find_string(head, str) == 0) {
        add_n(head, str);
    }
}

void rem_ent(struct node **head, struct node *ent) {
    while ((*head) != ent) {
        head = &((*head)->next);
    }
    (*head) = ent->next; 
    
    free(ent); 
}

void fini_list(struct node **head) {
    while ((*head) != NULL) {
        rem_ent(head, *head); 
        head = &((*head)->next);    
    }
}

int main() {
    struct node *head = NULL; 

    insert(&head, "electric");
    print_list(head); 

    insert(&head, "calcolatori");
    print_list(head);

    insert(&head, "prova pratica");
    print_list(head);

    insert(&head, "calcolatori");
    print_list(head);
    fini_list(&head);
    //printf("lunghezza media = %f\n", avg_word_lenght(head)); 
    return 0; 
}

也许错误可能是愚蠢的,但我花了很多时间调试没有成功。

由于冗余语句

,函数fini_list调用了未定义的行为
head=&((*head)->next);  

因为函数rem_ent已经设置了指针的新值head

void rem_ent(struct node** head, struct node * ent){
    while((*head) != ent){
        head= &((*head)->next);
        }
    (*head)= ent->next; 
    
    free(ent); 
}

删除语句

void fini_list(struct node** head){
    while((*head) != NULL){
        rem_ent(head, *head); 
        }
}

同样把函数add_n改成下面的方式

// insert a new node in head
void add_n(struct node ** head, char* str){
    struct node * new; 
    new = malloc(sizeof(struct node)); 
    if (new == NULL) {
        printf("Not enough memory\n");
        exit(EXIT_FAILURE);
        }
        new->word= str; 
        new->next = NULL; 
        if ((*head)==NULL){
            (*head)=new;    
        }
        else
        {
            while((*head)->next != NULL){
                head = &(*head)->next;}
            (*head)->next = new;
        }
}

下次将代码格式化为可读的方式。

一般来说,您应该为将存储在列表节点中的字符串动态分配内存。