这个链表中会有内存泄漏吗

Will there be a memory leak in this Linked list

本文关键字:内存 泄漏 链表      更新时间:2024-05-09

嗨,目前我一直在磨练我的数据结构技能,以便成为一名优秀的游戏开发人员,我正在学习链表,并制作了一个带有插入、删除和递归插入以及反转链表的链表程序。你们能告诉我我在这里吗?正确地清除用新操作员创建的分配内存吗,我得到了所需的输出,但我担心内存泄漏。。。请保持温和的目标仍在学习。

class Node
{
int data;
Node *Next;
public:
int GetData()
{
return data;
}
void SetData(int Data)
{
data = Data;
}
Node *GetNext()
{
return Next;
}
void SetNext(Node *next)
{
Next = next;
}
};
void Insert(Node **Head, int x)
{
Node *temp = new Node();
temp->SetData(x);
temp->SetNext(*Head);
*Head = temp;
}
void InsertAt(Node **Head, int x, int n)
{
if (n == 0)
{
std::cout << "The Given data at 'n' cannot be assigned to nulln";
}
Node *temp = new Node();
temp->SetData(x);
if (n == 1)
{
temp->SetNext(nullptr);
*Head = temp;
return;
}
Node *temp2 = *Head;
if (Head == nullptr)
{
std::cout << "The Given data cannot be assigned to nulln";
}
for (int i = 0; i < n - 2; i++)
{
temp2 = temp2->GetNext();
}
temp->SetNext(temp2->GetNext());
temp2->SetNext(temp);
}
void AppendList(Node **Head, int Data)
{
Node *temp = new Node();
Node *LastNode = *Head;
temp->SetData(Data);
temp->SetNext(nullptr);
if (*Head == nullptr)
{
*Head = temp;
return;
}
// else Traverse till last node.
while (LastNode->GetNext() != nullptr)
{
LastNode = LastNode->GetNext();
}
LastNode->SetNext(temp);
}
void DeleteNode(Node **Head, int n)
{
Node *temp = *Head;
if (n == 1)
{
*Head = temp->GetNext();
std::cout << "nAfter Deletion of Head Noden";
return;
}
for (int i = 0; i < n - 2; i++)
{
temp = temp->GetNext();
}
Node *temp2 = temp->GetNext();
temp->SetNext(temp2->GetNext());
std::cout << "After Deletion of Noden";
}
Node *ReverseList(Node *Head)
{
Node *Current, *Prev, *next;
Current = Head;
Prev = nullptr;
while (Current != nullptr)
{
next = Current->GetNext();
Current->SetNext(Prev);
Prev = Current;
Current = next;
}
Head = Prev;
return Head;
}
int LinkedList_Count(Node *Head)
{
int count = 0;
Node *Current = Head;
while (Current != nullptr)
{
count++;
Current = Current->GetNext();
}
std::cout << "Number of Elements: " << count;
return count;
}
void PrintList(Node *Head)
{
std::cout << "Data list : ";
while (Head != nullptr)
{
std::cout << " " << Head->GetData();
Head = Head->GetNext();
}
std::cout << "n";
}
//Print Listed using Recursion
void Recursion_Print(Node *Head)
{
if (Head == nullptr)
{
return;
}
std::cout << ' ' << Head->GetData(); //comment to Do Reverse the Linked list
Recursion_Print(Head->GetNext());
//std::cout << ' ' << Head->GetData();//unComment to Reverse the linked List recursively
}
Node *RecursiveRevList(Node *Head)
{
Node *temp;
if (Head->GetNext() == nullptr)
{
temp = Head;
return temp;
}
temp = RecursiveRevList(Head->GetNext());
Head->GetNext()->SetNext(Head);
Head->SetNext(nullptr);
return temp;
}
void RunList()
{
Node *Head = NULL;
//AppendList(&Head, 16);
Insert(&Head, 6);
Insert(&Head, 7);
Insert(&Head, 8);
InsertAt(&Head, 18, 2);
std::cout << "Data list : n";
Recursion_Print(Head);
std::cout << 'n';
LinkedList_Count(Head);
DeleteNode(&Head, 1);
//Head = ReverseList(Head);
Head = RecursiveRevList(Head);
PrintList(Head);
LinkedList_Count(Head);
delete Head;
}

您正在编写C风格的代码;在C++中,应该避免显式调用new。您的示例太长,无法重写,但这里有一个非常小的开始:

#include <memory>
class Node
{
int data;
std::shared_ptr<Node> Next;
// ...
void Insert(std::shared_ptr<Node>& Head, int x)
{
auto temp = std::make_shared<Node>();
// ...
}

(请注意,std::unique_ptr可能是比std::shared_ptr更好的选择,但这会导致复制Node的复杂性,而你现在"很高兴"没有意识到这一点。(

而且,在实践中,您应该真正使用std::list(在您的情况下为std::list<int>(,而不是自己编写。一旦你精通使用std::list(以及像std::vector这样的朋友(,你将能够更好地";滚你自己的">

正如许多学者在评论中指出的那样,您的程序中存在内存泄漏。删除节点时,实际上并没有释放分配的内存位置。正确的方式?使用delete从程序中取消分配内存。

我建议你根据经验来学习,当用C或C++编程时,如果你在程序中的某个地方分配动态内存,那么毫无疑问,你会有一些删除方法,你应该使用free()delete来从堆中释放内存。

以下是一些可能对您有所帮助的资源。

  • https://www.geeksforgeeks.org/g-fact-30/
  • https://www.geeksforgeeks.org/delete-in-c/
  • https://en.cppreference.com/w/cpp/language/delete(如果你是初学者,可能会有点难(