我正在编写一个删除链表中最后一个节点的函数。这就是我所拥有的,我在网上搜索解决方案的其他代码非常相似(我发现了几个),但是当我执行它时,它会在删除链表的最后一个元素时创建某种无限循环(它删除其他元素就好了)。
以下是我想象的导致问题的代码:
void delete_final(Node* head){
if(head == NULL) {
return; }
if(head->next == NULL) {
delete head;
head = NULL;
return;
}
//other code
}
我想这是内存的一个问题(特别是在删除头;声明之后),但我真的卡住了,并且会感谢任何帮助或解释为什么这不起作用(我可能没有非常好理解C ++中的指针和内存,我只是从它开始)
这是我的节点代码供参考:
struct Node {
int key;
Node* next;
};
感谢您的帮助!
答案 0 :(得分:3)
原始代码:
void delete_final(Node* head){
if(head == NULL) {
return; }
if(head->next == NULL) {
delete head;
head = NULL;
return;
}
//other code
}
"其他代码"未指定,但如果列表只有一个节点,则上面的代码将
删除第一个节点,
更新本地指针head
,它不会更新实际参数,因为通过值传递。
因此,在这种情况下,调用代码将留下一个悬空指针,一个指向被破坏对象的指针,或指向此类对象的指针。任何使用这种指针的行为都是Undefined Behavior。它似乎可以起作用,或者崩溃,或者只是默默地使脏字纹身出现在你的额头上 - 任何东西......
一种解决方法是通过引用传递第一个指针:
void delete_final(Node*& head){
if(head == nullptr) {
return; }
if(head->next == nullptr) {
delete head;
head = nullptr;
return;
}
//other code
}
用于处理链接列表的一个很好的帮助函数是unlink
:
auto unlink( Node*& p )
-> Node*
{
Node* const result = p;
p = p->next;
return result;
}
实现可能有点微妙,但你需要记住使用它的是它更新你作为参数传递的指针,它应该是第一个节点指针或{ {1}}列表中的指针,并返回指向未链接节点的指针。
所以,例如你可以做到
next