C++中的链表析构函数:我应该删除吗?

Linked List destructor in C++: should I delete?

本文关键字:我应该 删除 析构函数 链表 C++      更新时间:2023-10-16

我已经开始在C++中实现一些数据结构,从链表开始。来自Java背景,我仍然在思考指针和对象的生命周期。

链接列表:

struct Node
{
    int data;
    Node *next;
};
class LinkedList
{
private:
    Node *head;
    Node *tail;
    int length;
public:
    LinkedList();
    ~LinkedList();
    void addToHead(Node &newHead);
    void popHead();
    void printList();
};

然后我像这样实现它:

LinkedList::LinkedList()
{ 
    head = NULL;
    tail = NULL;
    length = 0;
}
LinkedList::~LinkedList(){}
void LinkedList::addToHead(Node& newHead)
{
    newHead.next = head;
    head = &newHead;
    length++;
}
void LinkedList::popHead()
{
    Node *currHead = head;
    head = head->next;
    length--;
}
void LinkedList::printList()
{
    Node *curr = head;
    while(curr)
    {
        curr = curr->next;  
    }
}

最后是一个简单的主要:

int main()
{
    LinkedList list;
    Node n1 = {3};
    Node n2 = {4};
    Node n3 = {5};
    list.addToHead(n1);
    list.addToHead(n2);
    list.addToHead(n3);
    list.printList();
    list.popHead();
    list.printList();
    return 0;
}

这是一个相当幼稚的实现,我想知道我是否必须提供一个适当的析构函数,在迭代时删除 Node* 指针。每当我尝试添加它时,程序都会导致内存错误,我认为正在分配的内存也在主节点结束时被释放,因为所有节点都在那里。

我应该修复我的析构函数吗?我应该更改整个界面吗?

提前感谢!

虽然你的代码中没有内存泄漏,但我认为你应该改变你的界面。

你的链表没有做你可能认为它做的事情 - 拥有它的内容。一个不拥有其内容的链表是一个奇怪的野兽,可能是你不想要的。

让它拥有所有权的一种简单方法是更改您的设计以使用std::unique_ptr而不是原始指针。然后,您的addToHead函数将更改为采用std::unique_ptr r 值引用指针(或者如果太高级,则只是在内部创建新std::unique_ptr的原始指针)

这是您的实现更改为使用 std::unique_ptr 。它有点粗糙,但应该让你上路:

#include <memory>
struct Node
{
    Node(int i) : data(i) 
    {}
    int data;
    std::unique_ptr<Node> next;
};
class LinkedList
{
private:
    std::unique_ptr<Node> head;
    Node *tail;
    int length;
public:
    LinkedList();
    ~LinkedList();
    void addToHead(std::unique_ptr<Node>&& newHead);
    void popHead();
    void printList();
};
LinkedList::LinkedList()
{ 
    head = NULL;
    tail = NULL;
    length = 0;
}
LinkedList::~LinkedList(){}
void LinkedList::addToHead(std::unique_ptr<Node>&& newHead)
{
    newHead->next = std::move(head);
    head = std::move(newHead);
    length++;
}
void LinkedList::popHead()
{
    head = std::move(head->next);
    length--;
}
void LinkedList::printList()
{
    auto* curr = head.get();
    while(curr)
    {
        curr = curr->next.get();  
    }
}
int main()
{
    LinkedList list;
    list.addToHead(std::make_unique<Node>(3));
    list.addToHead(std::make_unique<Node>(4));
    list.addToHead(std::make_unique<Node>(5));
    list.printList();
    list.popHead();
    list.printList();
    return 0;
}