C 用单个存储元素清除动态链表会使程序崩溃
在我的学术作业中,我的任务是使用链表创建一个动态集合ADT。我的程序运行正常,但当我试图清除一个只有一个元素(因此,是单个节点)的集合时,我的程序崩溃了 以下是如何定义我的链接列表:C 用单个存储元素清除动态链表会使程序崩溃,c,pointers,dynamic,linked-list,C,Pointers,Dynamic,Linked List,在我的学术作业中,我的任务是使用链表创建一个动态集合ADT。我的程序运行正常,但当我试图清除一个只有一个元素(因此,是单个节点)的集合时,我的程序崩溃了 以下是如何定义我的链接列表: typedef struct node{ int value; struct node *next; }Node; typedef struct List{ Node *head; Node *tail; }*SetList; 以下是相关功能: #include <s
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;
}
#包括
#包括
#包括
#包括“List.h”
SetList ListCreate(){
集合列表lptr;
lptr=malloc(sizeof(SetList));
lptr->head=NULL;
lptr->tail=NULL;
返回lptr;
}
SetList ListAdd(SetList lptr,int x){
if(列表是(x,lptr)的元素){
puts(“值已存在,请输入唯一值”);
}
否则{
Node*new=malloc(sizeof(Node));
新建->值=x;
新建->下一步=空;
如果(lptr->head==NULL){
lptr->head=新建;
lptr->tail=new;
}
否则{
lptr->tail->next=新建;
lptr->tail=new;
}
}
返回lptr;
}
SetList ListRemove(SetList lptr,int x){
如果(lptr==NULL){
puts(“内存分配失败。正在关闭”);
退出(退出失败);
}
else如果(!List_是(x,lptr)的元素_){
看跌期权(“价值未设定”);
}
否则如果(lptr->head==NULL){
puts(“集合为空。无法删除不存在的集合”);
}
否则{
如果(lptr->head->value==x){
Node*tempnode=malloc(sizeof(Node));
tempnode=lptr->head;
lptr->head=tempnode->next;
自由(tempnode);
}
否则{
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;
自由(tempnode);
}
}
返回lptr;
}
设置列表清除(设置列表lptr){
SetList templist=ListCreate();
圣殿骑士=lptr;
while(圣堂武士->头!=NULL){
ListRemove(templist,templist->head->value);
圣堂武士->头=圣堂武士->头->下一步;
}
自由(圣殿骑士);
返回lptr;
}
我在指针方面不是很有经验,所以我不完全确定问题是从哪里来的。删除存储了单个元素的列表是可行的,但清除它却不行
提前感谢您的阅读。您的清除功能不会改变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
。sizeof(SetList)
是指针的大小,您需要sizeof(struct List)
或sizeof*lptr
;我发现您的代码中至少有三个内存泄漏,您丢弃了malloc
的返回值。此外,你还返回了释放的指针。当涉及到内存泄漏时,我不太明白你在说什么,因为我的讲座不是特别好,我不得不在网上查找很多东西。你能详细说明吗?你说得对。因此,在您的评论之后,我决定循环while(lptr->head!=lptr->tail),然后在循环之后,我包括另一个ListRemove(lptr,lptr->head->value),以删除剩余的一个值,这似乎有效。