C++ 编写 LinkedList 析构函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2265967/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Writing a LinkedList destructor?
提问by kevin
Is this a valid LinkedList destructor? I'm still sort of confused by them.
这是一个有效的 LinkedList 析构函数吗?我仍然对他们感到困惑。
I want to make sure I'm understanding this correctly.
我想确保我正确理解了这一点。
LinkedList::~LinkedList()
{
ListNode *ptr;
for (ptr = head; head; ptr = head)
{
head = head->next
delete ptr;
}
}
So at the beginning of the loop, pointer ptr is set to hold the address of head, the first node in the list. head is then set to the next item, which will become the beginning of the list once this first deletion takes place. ptr is deleted, and so is the first node. With the first iteration of the loop, pointer is set to head again.
因此在循环开始时,指针 ptr 被设置为保存 head 的地址,即列表中的第一个节点。然后将 head 设置为下一项,一旦发生第一次删除,它将成为列表的开头。ptr 被删除,第一个节点也被删除。在循环的第一次迭代中,指针再次设置为头。
The thing that concerns me is reaching the very last node. The condition "head;" should check that it is not null, but I'm not sure if it will work.
我关心的事情是到达最后一个节点。条件“头”;应该检查它是否为空,但我不确定它是否有效。
Any help appreciated.
任何帮助表示赞赏。
回答by sharptooth
Why not do it much much simpler - with an elegant while
-loop instead of trying to carefully analyze whether that overcompilcated for
-loop is correct?
为什么不做得更简单——使用优雅的while
-loop 而不是尝试仔细分析过度for
编译的 -loop 是否正确?
ListNode* current = head;
while( current != 0 ) {
ListNode* next = current->next;
delete current;
current = next;
}
head = 0;
回答by paxdiablo
You can run it through a debugger or you can run it through that bit of wetware inside your skull - both will show you that it works fine. For example, let's start with the list:
您可以通过调试器运行它,也可以通过头骨内的那个湿件运行它 - 两者都会向您表明它工作正常。例如,让我们从列表开始:
head(47) -> [47]single_node -> [NULL]end-of-list.
Running that list through your statements:
通过您的语句运行该列表:
ptr = head
setsptr
to 47.head
is non-zero so enter loop.head = head->next
setshead
to NULL.delete ptr
will delete thesingle_node
.ptr = head
setsptr
to NULL.head
is now NULL (0) so exit loop.
ptr = head
设置ptr
为 47。head
非零所以进入循环。head = head->next
设置head
为 NULL。delete ptr
将删除single_node
.ptr = head
设置ptr
为 NULL。head
现在是 NULL (0) 所以退出循环。
There you go, you've deleted the only entry in the list and head
is now set to NULL. That's all you need to do.
好了,您已经删除了列表中唯一的条目,head
现在设置为 NULL。这就是你需要做的。
You can do a similar thing with a longer list or an empty list, you'll find it's still okay (there's no real difference between a one-element list and a fifty-element list).
你可以用更长的列表或空列表做类似的事情,你会发现它仍然可以(单元素列表和五十元素列表之间没有真正的区别)。
As an aside, I'm not a big fan of treating pointers as booleans - I'd rather write it as something like:
顺便说一句,我不太喜欢将指针视为布尔值 - 我宁愿将其写为:
for (ptr = head; head != NULL; ptr = head)
It makes the code read better in my opinion and you don't really sacrifice any performance (unless you have a brain-dead compiler). But that's a matter of taste.
在我看来,它使代码可读性更好,并且您并没有真正牺牲任何性能(除非您有一个脑死亡的编译器)。但这是一个品味问题。
Re your comment:
回复您的评论:
The thing that concerns me is reaching the very last node. The condition "head;" should check that it is not null, but I'm not sure if it will work.
我关心的事情是到达最后一个节点。条件“头”;应该检查它是否为空,但我不确定它是否有效。
It will work. A value of zero will be treated as false so you'll find that you never dereference head->next when head is NULL simply because you will have exited the loop body before that point (or not even entered the body if the list is empty).
它会起作用。零值将被视为 false,因此您会发现当 head 为 NULL 时您永远不会取消引用 head->next 仅仅因为您将在该点之前退出循环体(或者如果列表为空甚至不进入体) )。
Any other pointer value will be treated as true and you will enter or continue the loop body.
任何其他指针值都将被视为真,您将进入或继续循环体。
回答by James Curran
The condition "head;" should check that it is not null, but I'm not sure if it will work.
条件“头”;应该检查它是否为空,但我不确定它是否有效。
Yes, "head" by itself is the same as "head != null" -- but why use a meaningless typing shortcut if even you find it confusing? It's only 6 more keystrokes (and generates identical machine code), so go for the long form.
是的,“head”本身与“head != null”是一样的——但如果你觉得它很混乱,为什么还要使用毫无意义的输入快捷方式呢?只需再敲 6 次键(并生成相同的机器代码),所以选择长格式。
Additionally, your code is a bit more complicated than necessary because you are using a for()
construct. Why not use a while()
? Your code will be much cleaner.
此外,您的代码比必要的要复杂一些,因为您使用的是for()
构造。为什么不使用while()
? 你的代码会更干净。
Finally, I realize you are doing this as a learning exercise, but keep in mind that list<> is in the standard library --- Linked lists are official a "Solved Problem".
最后,我意识到你这样做是作为一个学习练习,但请记住 list<> 在标准库中——链表是官方的“已解决问题”。
回答by diwakar
Tested OK
测试正常
Destructor for class List
类 List 的析构函数
List::~List()
{
Node *n = this->front, *current = NULL; //initialization part
while(n) //start cleanup of nodes of the list
{
current = n;
n=n->next;
delete(current);
}
front = end = NULL;
}
回答by HN Learner
This one is a better approach for freeing/deleting the memory using destructor of a Linked-List.
这是使用链表的析构函数释放/删除内存的更好方法。
List()::~List()
{
for( Link* ptr= Head; Head; Head= Head->next)
{
delete ptr;
}
}
回答by Hans W
Your code might be correct, you should try running it with e.g. valgrind and see what it says. However, I would write it like this:
您的代码可能是正确的,您应该尝试使用例如 valgrind 运行它并查看它的内容。但是,我会这样写:
for (ListNode *current = head, *next; current; current = next) {
next = current->next;
free(current);
}