如何正确释放分配有链表的内存?

时间:2015-12-02 15:44:11

标签: c++

我正在编写一个使用链表的程序,在我的代码中,我使用“new”关键字创建了一个对象指针。根据我的理解,每次使用新关键字时,您还需要删除,我想知道我是否正确执行此操作。

git rev-list

2 个答案:

答案 0 :(得分:0)

要避免此问题,只需使用std::shared_ptr<Node>即可。一旦指针超出范围(如果没有其他共享指针指向它),指针将释放它指向的内容。

如果你想练习使用new / delete,你会误解它的作用:使用new创建一个新节点,然后以某种方式使用该节点。只有当不再需要节点时才删除它。现在发生以下情况:

Node* tmpNode;
tmpNode = new Node;        // You get a new Node on heap.
tmpNode->setNext(NULL);    
tmpNode->setData(tmpCard);
head = tmpNode;            // Head now points to the new Node. All is well.
delete tmpNode;            // The Node both tmpNode and head point to is deleted!

现在,head和tmpNode都包含指向未分配内存的指针。当您访问它时,您会得到未定义的行为。您可能想要的是删除List的析构函数中的所有节点,而不是其他地方。

答案 1 :(得分:0)

你完全错误地做了。

  • 您正在立即引入新的head,然后delete新的head。这非常糟糕。
  • 您的remove()功能几乎没有任何功能。它创建一个新的Node,为其设置一些参数,然后检索应该相同的数据集,并delete新的Node

试试这个:

#include"gameClass.h"
#include"card.h"
#include"list.h"
#include"node.h"

using namespace std;

List::List()
{
    head = NULL;
}

List::~List()
{
    // delete all node currently have instead of only head
    while (head != NULL)
    {
        Node* tmpNode = head;
        delete head;
        head = tmpNode;
    }
}

void List::add(Card* tmpCard)
{
    if (head == NULL)
    {
        Node* tmpNode;
        tmpNode = new Node;
        tmpNode->setNext(NULL);
        tmpNode->setData(tmpCard);
        head = tmpNode;
        // do not delete the new node here!
    }
    else
    {
        Node* tmpNode;
        tmpNode = new Node;
        tmpNode->setNext(head); // the new head should be linked to current head, not the next node of current head
        tmpNode->setData(tmpCard);
        head = tmpNode;
        // do not delete the new node here!
    }
}

 Card * List::remove()
{
    if (head != NULL)
    {
        //Card* tmpCard;
        Node* tmpNode;

        // no creating new nodes to remove the first node
        tmpNode = head->getNext(); // remember where the next node is
        delete head; // remove the head
        head = tmpNode; // move the head
    }
    return nullptr;
}

UPDATE:如果要将指针返回到要删除的节点中的卡片,remove()函数将如下所示:

 Card * List::remove()
{
    if (head != NULL)
    {
        Card* tmpCard;
        Node* tmpNode;

        tmpCard = head->getData(); // remember where the card pointed by head is
        tmpNode = head->getNext(); // remember where the next node is
        delete head; // remove the head
        head = tmpNode; // move the head
        return tmpCard; // return the card
    }
    return nullptr; // there are no cards in this list
}
相关问题