删除链表中不存在的节点导致分段错误
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)
这样,如果curr
是NULL
,则不会计算第二个条件(称为short-circuit evaluation)。
所以我是数据结构的新手,我正在尝试链表。我制作了一个 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)
这样,如果curr
是NULL
,则不会计算第二个条件(称为short-circuit evaluation)。