我需要删除单链表中动态分配的对象吗?
Posted
技术标签:
【中文标题】我需要删除单链表中动态分配的对象吗?【英文标题】:Do I need to delete a dynamically allocated object in Singly Linked List? 【发布时间】:2021-06-07 04:28:22 【问题描述】:我目前正在学习链接列表,并且已经使用 Append 和 Prepend 方法实现了一个单链表,其中我使用“new”运算符在堆上分配了 Node 类型的对象。我是否需要使用“删除”在堆上释放对象,如果需要,我该怎么做? 这是我的代码:-
class List
private:
class Node
public:
int data;
Node* next;
Node()
data = 0;
next = NULL;
Node(const int& data)
this->data = data;
;
Node* head;
public:
List()
head = NULL;
void Append(const int&val);
void Prepend(const int&val);
void DisplayAll();
;
void List::Append(const int&val)
Node* n = new Node(val); //dynamically allocated
if (head == NULL)
head = n;
return;
Node* temp = NULL;
temp = head;
while (temp->next != NULL)
temp = temp->next;
temp->next = n;
void List::Prepend(const int&val)
Node* node = new Node(val);//dynamically allocated
if (head == NULL)
head = node;
return;
node->next = head;
head = node;
void List::DisplayAll()
Node* temp = head;
while (temp != NULL)
std::cout << temp->data << ' ';
temp = temp->next;
【问题讨论】:
Any 如果不再需要动态分配的数据,则需要为delete
d,否则会出现内存泄漏。这也包括您的节点。
你可以编写一个析构函数(例如~Node() ...
)来为你做这件事。 (这将是确保班级自行清理的正确方法)例如~Node() while (head) Node *victim = head; head = head->next; delete victim;
另外,如果你添加一个tail
指针(例如Node *head, *tail;
)并且总是让tail
指向你列表中的最后一个节点,你可以在O(1)时间内append
无需迭代。
旁注:习惯于实现构造函数的初始化列表(不要与std::initializer_list
混淆):List() : head(nullptr)
。这比默认初始化+赋值更喜欢直接初始化,另外一些成员类型(常量、引用、不可赋值的)only 可以这样初始化。此外,您应该更喜欢 C++ keywords (nullptr
) 而不是旧的(过时的?)C macros (NULL
)。
虽然适合学习,但请记住std::forward_list
已经在做同样的事情,你应该稍后使用它而不是重新发明的***。关于学习:下一步是将您的列表转换为模板,以便能够添加任意数据类型。
【参考方案1】:
对于初学者来说这个构造函数
Node(const int& data)
this->data = data;
不初始化数据成员next
。因此成员函数Append
和Prepend
有一个错误
void List::Append(const int&val)
Node* n = new Node(val); //dynamically allocated
if (head == NULL)
head = n;
return;
//...
和
void List::Prepend(const int&val)
Node* node = new Node(val);//dynamically allocated
if (head == NULL)
head = node;
return;
//...
头节点的数据成员next
有一个不确定的值。
你可以简单地声明类Node
struct Node
int data;
Node* next;
;
Node* head = nullptr;
在这种情况下,例如函数 Prepend
看起来像
void List::Prepend( const int &val )
head = new Node val, head ;
构造函数看起来像
List() = default;
要释放列表中所有已分配的节点,您可以再编写两个成员函数clear
和调用函数clear
的析构函数。
例如
#include <functional>
//...
class List
//...
public:
void clear()
while ( head ) delete std::exchange( head, head->next );
~List() clear();
//...
此外,您至少应该编写一个复制构造函数和复制赋值运算符,或者将它们定义为已删除。
【讨论】:
以上是关于我需要删除单链表中动态分配的对象吗?的主要内容,如果未能解决你的问题,请参考以下文章