C ++为什么创建一个新节点来删除堆栈上的节点错误

时间:2017-10-19 15:30:03

标签: c++ stack new-operator singly-linked-list delete-operator

我在课堂上学习单链表列表,我遇到了这个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指向一个新节点(也就是新的内存地址),然后我将该内存地址的值设置为顶部的值堆栈的内存地址。我将堆栈的顶部移动到下一个节点,然后删除我创建的这个临时节点,但是因为我将它声明为一个新的节点,它只具有旧堆栈顶部的值,所以它实际上并没有与该节点的关系。堆栈节点的旧顶部从堆栈中删除,但内存未正确释放。这是对的吗?

1 个答案:

答案 0 :(得分:0)

第一个答案是错误的。

tmp = new Node;
value = head->data;
tmp = head;
delete tmp;

这会删除head指针,这就是你想要的。但该函数在tmp创建一个新的内存分配,然后立即用值head覆盖指针。您现在已经丢失了指向已分配数据的指针。这是内存泄漏。