C语言 清除具有单个存储元素的动态链表崩溃程序



对于我的学术作业,我的任务是使用链表创建一个动态集 ADT。我的程序运行正常,但是当我尝试清除只有一个元素(尔格,单节点)的 Set 时,我的程序崩溃了。

以下是我的链表的定义方式:

typedef struct node{
    int value;
    struct node *next;
}Node;
typedef struct List{
    Node *head;
    Node *tail;
}*SetList;

以下是相关功能:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "List.h"
SetList ListCreate(){
    SetList lptr;
    lptr = malloc(sizeof(SetList));
    lptr->head = NULL;
    lptr->tail = NULL;
    return lptr;
}
SetList ListAdd(SetList lptr, int x){
    if(List_Is_Element_Of(x, lptr)){
            puts("Value already exists, enter a unique value");
    }
    else{
        Node *new = malloc(sizeof(Node));
        new->value = x;
        new->next = NULL;
        if(lptr->head == NULL){
            lptr->head = new;
            lptr->tail = new;
        }
        else{
            lptr->tail->next = new;
            lptr->tail = new;
        }
    }
        return lptr;
}

SetList ListRemove(SetList lptr, int x){
    if(lptr == NULL){
            puts("Memory Allocation Failed. Shutting down.");
            exit(EXIT_FAILURE);
    }
    else if(!List_Is_Element_Of(x, lptr)){
        puts("Value is not in set");
    }
    else if(lptr->head == NULL){
        puts("Set is empty. Cannot remove that which does not exist");
    }
    else{
        if(lptr->head->value == x){
        Node *tempnode = malloc(sizeof(Node));
        tempnode =  lptr->head;
        lptr->head = tempnode->next;
        free(tempnode);
        }
        else{
        Node *tempnode = malloc(sizeof(Node));
        tempnode =  lptr->head;
        Node *tempnode2 = malloc(sizeof(Node));
        tempnode2 = tempnode;
        while(tempnode->value != x){
            tempnode2 = tempnode;
            tempnode = tempnode->next;
        }
        tempnode2->next = tempnode->next;
        free(tempnode);
        }
    }
    return lptr;
}
SetList ListClear(SetList lptr){
    SetList templist = ListCreate();
    templist = lptr;
    while(templist->head!= NULL){
        ListRemove(templist, templist->head->value);
        templist->head = templist->head->next;
    }
    free(templist);
    return lptr;
}

我在指针方面不是很有经验,所以我不完全确定问题来自哪里。删除存储了单个元素的列表是有效的,但清除它则不起作用。

提前感谢您的阅读。

你的 clear 函数不会改变 Tail,尽管你似乎没有使用 tail(除了你在添加节点时给它一个与 head 不同的节点?

当 clear 删除最后一个元素

时,head 应为 null,因此在删除最后一个元素后取消引用它会很糟糕。

加上@NotLikeThat说的话。

如果我

没看错的话:

SetList ListClear(SetList lptr){
    SetList templist = ListCreate();   // Create a new list
    templist = lptr;                   // Immediately throw away the new list
                                       //  by overwriting the pointer with the old one
    while(templist->head!= NULL){      // Delete everything from the old list
        ListRemove(templist, templist->head->value);
        templist->head = templist->head->next;
    }
    free(templist);                    // Free the old list
    return lptr;                       // Return a pointer to freed memory
}

如果要通过删除所有元素来清除列表,则无需创建新列表,只需遍历现有列表,删除元素,直到它为空。该函数中真正需要的只是while循环。

我认为ListRemove()还应该检查它是否删除了最后一个元素并相应地更新tail

最新更新