【问题标题】:C++ why is creating a new node to delete a node on a stack wrongC ++为什么创建一个新节点来删除堆栈上的一个节点错误
【发布时间】:2018-03-31 16:59:14
【问题描述】:

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

【问题讨论】:

  • 是的,看起来您找到的第一个答案泄漏了为tmp 分配的内存。我建议对它发表评论,以便向任何可能找到它的人指出。
  • 第一个答案太错误了,甚至都不好笑。我投了反对票,你也应该这样做。
  • 我刚刚投了反对票。我发现它之前没有得到任何反对意见令人不安。
  • 顺便说一句。在纸上画出你的堆栈。链接的数据结构可以很好地可视化,然后很容易看到会发生什么。
  • 错误不仅因为无故内存泄漏,而且(更重要的是)因为复杂性错误。您不应该遍历整个堆栈来推送或弹出元素。

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


【解决方案1】:

第一个答案是错误的。

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

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

【讨论】:

    猜你喜欢
    • 2016-08-26
    • 1970-01-01
    • 1970-01-01
    • 2012-09-18
    • 2021-07-19
    • 1970-01-01
    • 2021-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多