【问题标题】:C++ delete not working?C ++删除不起作用?
【发布时间】:2011-02-09 05:49:06
【问题描述】:

我遇到了删除和析构函数的问题(我确定我在这里犯了一个愚蠢的错误,但目前还没有弄清楚)。

当我进入析构函数并尝试在指针上调用 delete 时,消息显示“无法访问地址 some address 处的内存。”

相关代码为:

/*
 * Removes the front item of the linked list and returns the value stored
 * in that node.
 *
 * TODO - Throws an exception if the list is empty
 */
std::string LinkedList::RemoveFront()
{
    LinkedListNode *n = pHead->GetNext(); // the node we are removing
    std::string rtnData = n->GetData(); // the data to return

    // un-hook the node from the linked list
    pHead->SetNext(n->GetNext());
    n->GetNext()->SetPrev(pHead);

    // delete the node
    delete n;
    n=0;

    size--;
    return rtnData;
}

/*
 * Destructor for a linked node.
 *
 * Deletes all the dynamically allocated memory, and sets those pointers to 0.
 */
LinkedListNode::~LinkedListNode()
{
    delete pNext; // This is where the error pops up
    delete pPrev;
    pNext=0;
    pPrev=0;
}

【问题讨论】:

    标签: c++ destructor delete-operator


    【解决方案1】:

    您似乎正在从析构函数中删除列表的下一个和上一个节点。其中,如果 pNextpPrevLinkedListNode*,则意味着您正在递归删除整个列表 :-(

    试试这个:

    std::string LinkedList::RemoveFront()
    {
        LinkedListNode *n = pHead->GetNext(); // the node we are removing
        std::string rtnData = n->GetData(); // the data to return
    
        // un-hook the node from the linked list
        pHead->SetNext(n->GetNext());
        n->GetNext()->SetPrev(pHead);
    
        n->SetNext(0);
        n->SetPrev(0);
        // delete the node
        delete n;
        n=0;
    
        size--;
        return rtnData;
    }
    
    LinkedListNode::~LinkedListNode()
    {
    }
    

    (实际上,您甚至不需要将 prev 和 next 指针重置为 0,因为无论如何您都将删除节点。我保留了这些语句,因为它们至少使节点处于一致状态,这是总的来说是个好主意。如果您稍后更改内存管理策略并决定存储未使用的节点以供以后重用,这可能会有所不同。)

    【讨论】:

    • 当前节点中存储的下一个和上一个节点(每个节点包含一些字符串数据,以及指向列表中下一个和上一个节点的指针)。这是我们想要的行为,因为我们已经从链表中解开了这个节点,现在想要返回所有动态分配的内存编辑 - 等等,我想明白你在说什么..
    • @kyeana:您只想返回与您要删除的单个节点关联的内存
    • 比这更糟糕——这实际上会删除到列表末尾(在第一次删除时递归),然后尝试从最后一个节点的内部再次删除倒数第二个节点析构函数,这很可能是崩溃的地方。如果X、Y、Z是最后三个节点,~X删除Y,~Y删除Z,~Z再次删除Y。
    • 好的,这很有道理。我知道我在做一些愚蠢的事情 :) 感谢您的帮助。
    • 情况更糟。 Z 尝试删除其“Next”指向的任何内容,这可能是 NULL 或内存中的随机位置。
    【解决方案2】:

    您的LinkedListNode 似乎正在删除它的邻居,所以当您删除一个节点时,它会继续销毁整个列表 - 请注意,当您删除节点时,您没有将 pNextpPrev 设置为 NULL .

    即使在您希望销毁整个列表的情况下,您的LinkedListNode 析构函数也存在问题:同时拥有delete pNextdelete pPrev 将导致对同一个析构函数的多次调用(我认为最终是一个堆栈溢出)。

    【讨论】:

    • 天哪...节点2删除节点1和3,都尝试删除节点2,节点1和3各删除两次,然后节点2又被删除四次,.. .
    【解决方案3】:

    实际上,您不应该在节点中与邻居搞混。这是列表类要做的 - 正确连接它们。在析构函数中,您可以将它们设置为 null,但除非您动态分配了其他内容 - 您不必调用 delete

    【讨论】:

      猜你喜欢
      • 2012-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-25
      • 2018-10-18
      • 2010-09-06
      相关资源
      最近更新 更多