【发布时间】:2019-09-10 18:24:54
【问题描述】:
这个程序的目的是在链表的末尾添加一个可以通过ID删除的节点。
除了第一个节点之外,我可以毫无问题地删除所有节点。在删除第一个节点后尝试执行任何操作会导致意外行为,例如,如果我添加更多节点,链表将被完全清除,尝试在链表中显示数据时出现无限循环,或者出现错误“双重释放或损坏”。
删除节点
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;
}
如果我在删除第一个节点后退出程序,我会得到“双重释放或损坏”,如果我在删除第一个节点后添加一个新节点并尝试显示数据,则会导致无限循环。如果我删除第一个节点,并添加 2 个额外的节点,则链接列表将被清除,我可以退出而不会出错。
【问题讨论】:
-
删除第一个节点后你的函数应该返回什么?
-
抱歉回复晚了,它应该返回更新后的链表,如果它是链表中唯一的节点,它应该是 NULL,如果我理解正确的话。
-
应该,但真的吗?
-
在函数
delete_node()中,指针prev未初始化。如果p不为NULL 并且p->id == id,那么对prev做的第一件事就是赋值prev->next = p。即使访问prev->next(进行分配之前的必要步骤)也会给出未定义的行为。这将解释为什么删除第一个节点会失败 - 一旦行为未定义,您的程序中的所有赌注都将失败。
标签: c linked-list