删除链表中不存在的节点导致分段错误

Deleting node that doesn't exist in linked list causes segmentation fault

所以我是数据结构的新手,我正在尝试链表。我制作了一个 class 节点,其中包含一个 int 键、int del 和 Node* 接下来。 当我尝试通过给删除函数 (Del) 一个键来删除节点时,它非常适合头节点或列表中存在的任何节点,但是当我给出一个列表中不存在的键时,它 returns 与分段错误。

 void Node::Del(int k) // here k is the key given to search
  {
    Node *curr = head; // ptr that traverses the list
    Node *temp = NULL; // the pointer trails behind curr to store value of node one position behind curr

    while (curr->key != k && curr != NULL)
    {
        temp = curr;
        curr = curr->next;
    }

    if (curr == NULL) // if key not found (not working properly)
    {
        return;
    }

    else if (curr == head) // if head contains the key
    {
        head = curr->next;
        delete curr;
        return;
    }

    else if (curr->key == k) // if key exists in the node
    {
        temp->next = curr->next;
        delete curr;
    }
}

int main()
{
    Node n1;
    n1.Insert(1, 1);
    n1.Insert(2, 2);
    n1.Insert(3, 3);
    n1.Insert(4, 4);
    n1.Insert(5, 5);

    n1.Del(7);
    n1.print();
}

输出:

1 1
2 2
3 3
4 4
5 5

zsh: segmentation fault 

遍历后我有一个条件 if( curr == NULL ){ return;} 意味着它一直搜索到最后并没有找到密钥并退出循环(根据我的理解),而是它 returns分段错误。

在这一行 (curr->key != k && curr != NULL) 你应该先检查 curr 是否为空,然后再访问 curr 以检查它的键值,所以它应该是 (curr != NULL && curr->key != k).

说明: 当节点不存在时 - 我在你的代码中看到你假设节点键是唯一的 - 所以你仍然循环链表直到 curr 变为 null 并且 while 条件最后一次检查,此时 curr 为空,因此它访问一个 NULL 指针,这会引发您的分段错误。但是如果你首先检查 curr 是否为空,编译器会在继续检查后面的语句之前将 AND 条件视为假,这样你就安全了。

这一行有问题:

while (curr->key != k && curr != NULL)

第二个条件,意思是curr != NULL,是无关紧要的。应该反过来:

while (curr != NULL && curr->key != k)

这样,如果currNULL,则不会计算第二个条件(称为short-circuit evaluation)。