我在课堂上学习单链表列表,我遇到了这个stackoverflow页面,它给了我一些关于如何弹出节点的参考:
Pop function on Linked list stack
第一个答案使用以下代码弹出一个节点:
struct Node
{
int data;
Node *next;
};
int pop(Node *head)
{
while(head->next != NULL)
{
head = head->next;
}
int value;
Node *tmp;
tmp = new Node;
value = head->data;
tmp = head;
delete tmp;
return value;
}
第三个答案使用以下代码:
int pop( Node * &top )
{
int value = 0;
if ( top )
{
value = top->num;
Node *tmp = top;
top = top->next;
delete tmp;
}
return value;
}
现在,因为第一个答案我最初写的是我的pop函数:
// Pop the top element off of the stack and return its value.
StackElement Stack::Pop()
{
assert (!Empty());
StackElement poppedData = tos->data;
Node *temp = new Node;
temp = tos;
tos = tos->next;
delete temp;
return poppedData;
}
但是,我的老师说创建一个新节点来删除前一个节点会导致内存泄漏。
最终我改写了我的代码以匹配样式二:
StackElement Stack::Pop()
{
assert (!Empty());
StackElement poppedData = tos->data;
Node *temp = tos;
tos = tos->next;
delete temp;
return poppedData;
}
任何人都可以向我解释为什么第一次实施是错误的?当这个人在另一个stackoverflow问题上发布它时,我很惊讶没有人对此发表评论。在我看来,我正在创建一个Node类型的指针temp指向一个新节点(也就是新的内存地址),然后我将该内存地址的值设置为顶部的值堆栈的内存地址。我将堆栈的顶部移动到下一个节点,然后删除我创建的这个临时节点,但是因为我将它声明为一个新的节点,它只具有旧堆栈顶部的值,所以它实际上并没有与该节点的关系。堆栈节点的旧顶部从堆栈中删除,但内存未正确释放。这是对的吗?
答案 0 :(得分:0)
第一个答案是错误的。
tmp = new Node;
value = head->data;
tmp = head;
delete tmp;
这会删除head
指针,这就是你想要的。但该函数在tmp
创建一个新的内存分配,然后立即用值head
覆盖指针。您现在已经丢失了指向已分配数据的指针。这是内存泄漏。