删除链表中的节点 - 分段错误

Deleting node in linked list - segmentation fault

本文关键字:分段 错误 节点 链表 删除      更新时间:2023-10-16

问题需要从链表中删除节点,给定列表的头部指针和要删除的节点在列表中的位置。有关问题的更多详细信息,请访问:https://practice.geeksforgeeks.org/problems/delete-a-node-in-single-linked-list/1

代码返回分段错误,但不确定我哪里出错了。我的代码如下:

Node* deleteNode(Node *head,int x)
{
//Your code here
struct Node* temp = head;
if(x==0){
//change head
head = temp->next;
free(temp);
}
//find previous node of node to be deleted
for(int i=0; temp!=NULL && i<x-1; ++i){
//traverse
temp = temp->next;
}
//now temp should be pointing to previous node
//store pointer to next of node to be deleted
struct Node* next = temp->next->next;
free(temp->next);
temp->next= next;
}

您的代码包含许多可以取消引用空指针的位置。例如这里:

struct Node* temp = head;
if(x==0){
//change head
head = temp->next;
free(temp);
}

如果head已经是一个空指针。此外,您似乎假设这会更改调用方中的head变量,但事实并非如此。您必须传递双指针才能实现此目的。最后,看起来您的函数应该在free(temp);之后返回。

然后,看看这部分:

for(int i=0; temp!=NULL && i<x-1; ++i){
//traverse
temp = temp->next;
}
//now temp should be pointing to previous node
//store pointer to next of node to be deleted

不,它不一定指向节点,temp也可以包含一个空指针,这是 for 循环的第二个中断条件。您必须检查这一点,如果是这种情况,请纾困。

您应该在一开始和执行最后 3 行代码之前检查是否head == nullptr,如果temp == nullptr因为您可以退出 for 循环,因为用户尝试删除的节点超出了大小。

您还应考虑从函数返回void

你可以做这样的事情:

void deleteNode(Node *head,int x)
{
// this way you avoid dereferencing nullptr with temp->next later on
if(head == nullptr) return;
//Your code here
struct Node* temp = head;
if(x==0){
//change head
head = temp->next;
free(temp);
}
//find previous node of node to be deleted
for(int i=0; temp!=NULL && i<x-1; ++i){
//traverse
temp = temp->next;
}
//now temp should be pointing to previous node
//store pointer to next of node to be deleted
// you need to check to see if temp is nullptr here or if the node
// after temp is nullptr because either of those can cause you to 
// get a segmentation fault because of dereferencing a nullptr
if(temp == nullptr || temp->next == nullptr) return;
struct Node* next = temp->next->next;
free(temp->next);
temp->next= next;
}