C “接收”;“双重自由或腐败”;仅当删除链表的第一个节点时
该程序的目的是在链表的末尾添加一个节点,该节点可以通过ID删除 除第一个节点外,我可以删除每个节点而不出现问题。删除第一个节点后尝试执行任何操作都会导致意外行为,例如,如果添加更多节点,链表将被完全清除,尝试在链表中显示数据时出现无限循环,或者出现错误“双重释放或损坏” 删除节点C “接收”;“双重自由或腐败”;仅当删除链表的第一个节点时,c,linked-list,C,Linked List,该程序的目的是在链表的末尾添加一个节点,该节点可以通过ID删除 除第一个节点外,我可以删除每个节点而不出现问题。删除第一个节点后尝试执行任何操作都会导致意外行为,例如,如果添加更多节点,链表将被完全清除,尝试在链表中显示数据时出现无限循环,或者出现错误“双重释放或损坏” 删除节点 struct node* delete_node(struct node *list) { struct node* p = list; struct node* prev, *temp;
struct node* delete_node(struct node *list)
{
struct node* p = list;
struct node* prev, *temp;
int id;
printf("\nEnter ID: ");
scanf("%d", &id);
while(p != NULL)
{
if(p->id == id)
{
temp = p;
p = p->next;
prev->next = p;
free(temp);
printf("\nNode Deleted");
return list;
}
prev = p;
p = p->next;
}
printf("\nID not found");
return list;
}
添加节点
struct node *add_node(struct node *list)
{
struct node *p;
int id;
printf("\nEnter ID: ");
scanf("%d", &id);
for(p = list; p != NULL; p = p->next)
{
if(p->id == id)
{
printf("\nUser with this ID already exists.");
return list;
}
}
struct node *new_req;
struct node *q = list;
char username[UNAME_LEN], password[UNAME_LEN];
printf("\nEnter username: ");
read_line(username, UNAME_LEN);
printf("\nEnter password: ");
read_line(password, UNAME_LEN);
new_node = malloc(sizeof(struct node));
if(new_node == NULL)
{
printf("\nError allocating memory!");
return list;
}
strcpy(new_node->username, username);
strcpy(new_node->password, password);
new_node->id = id;
if(list == NULL)
{
new_node->next = NULL;
list = new_node;
return list;
}
while(q->next != NULL)
q = q->next;
new_node->next = q->next;
q->next = new_node;
return list;
}
如果我在删除第一个节点后退出程序,我将获得“双重自由或损坏”,如果我在删除第一个节点后添加一个新节点并尝试显示数据,它将导致无限循环。如果我删除了第一个节点,并添加了两个额外的节点,则链接列表将被清除,并且我可以毫无错误地退出。删除列表中的第一个节点时,您的删除代码无法正常工作。解决此问题的方法可能是:
if(p->id == id)
{
if(p == list)
list = list->next;
else
prev->next = p->next;
free(p);
printf("\nNode Deleted");
return list;
}
而且不再需要
temp
变量。删除第一个节点后,您的函数应该返回什么?很抱歉,响应太晚,它应该返回更新的链接列表,如果它是链接列表中唯一的节点,如果我理解正确,它应该为NULL。它应该,但确实如此?在函数delete_node()
中,指针prev
未初始化。如果p
不为空且p->id==id
则对prev
所做的第一件事是赋值prev->next=p
。甚至访问prev->next
(执行分配之前的必要步骤)也会产生未定义的行为。这将解释为什么删除第一个节点失败-一旦行为未定义,您的程序中的所有赌注都将被取消。很抱歉,响应太晚,我尝试使用此选项,但仍然存在相同的问题,我可以删除除第一个节点外的所有节点one@IAteYourCat:如何调用删除节点
?删除节点(新列表),在我的main中,我有struct request*new_list=NULL@IAteYourCat:它应该是new\u list=delete\u node(new\u list)
。这不是删除双链接列表中节点的正确方法。您需要更新两个指针。