导致 Seg 错误的 SingleLinkedList 的析构函数

Destructor of a SingleLinkedList Causing a Seg Fault

本文关键字:SingleLinkedList 析构函数 错误 Seg 导致      更新时间:2023-10-16

我正在用 c++ 编写一个单向链表,当在包含多个节点的列表上调用单向链表时,我的单向链表的析构函数会导致段错误。

我正在对链表类运行测试以确保它正常运行,并且在测试 PushFront 方法时遇到了问题。当我从测试函数中删除delete list行时,我意识到析构函数导致了 seg 错误,并且它运行良好而没有段错误(PushFront 测试函数只是一系列测试函数中的一个测试链表的各个方面。删除删除行后,调用这一系列测试函数的测试程序可以完美地完成执行,但是使用删除行会导致段错误。

这是链表的析构函数(带有用于调试目的的 cout 语句(:

// CSingleLinkedList Destructor
CSingleLinkedList::~CSingleLinkedList()
{
std::cout << "In Destructor" << std::endl;
CSingleLinkedList::CSingleLinkedNode* temp = head_;
std::cout << "temp = " << temp << std::endl;
while(temp != nullptr)
{
CSingleLinkedList::CSingleLinkedNode* toDelete = temp;
temp = temp->GetNext();
std::cout << "toDelete = " << toDelete << std::endl;
std::cout << "temp = " << temp << std::endl;
delete toDelete;
}
}

这是链接节点(只有数据成员value_(一个 int(和next_(指向下一个 CSingleLinkedNode 的指针((的析构函数:

// CSingleLinkedNode Destructor
CSingleLinkedList::CSingleLinkedNode::~CSingleLinkedNode()
{
delete next_;
}

这是我正在运行的测试函数,用于测试 PushFront 函数:

void TestListPushFront()
{
CSingleLinkedList* list = new CSingleLinkedList();
list->PushFront(1);
assert(list->GetFrontValue() == 1);
assert(list->GetBackValue() == 1);
assert(list->GetSize() == 1);
list->PushFront(2);
list->PushFront(3);
assert(list->GetFrontValue() == 3);
assert(list->GetBackValue() == 1);
assert(list->GetSize() == 3);
std::cout << "TestListPushFront Passed!" << std::endl;
delete list;
}

这是我在运行函数时看到的痕迹:

TestListPushFront Passed!
In Destructor
temp = 0x55ce050332e0
toDelete = 0x55ce050332e0
temp = 0x55ce050332c0
toDelete = 0x55ce050332c0
temp = 0x55ce050332a0
Segmentation fault

有人对为什么会发生这种赛格错误有任何想法吗?

您的CSingleLinkedNode析构函数具有以下语句:

delete next_;

一旦你的CSingleLinkedListdelete节点,该节点和所有后续节点就会被释放,因为你正在调用递归破坏

因此,当您的CSingleLinkedList析构函数销毁head_节点,然后尝试访问下一个节点时,它会崩溃,因为下一个节点已被销毁。 这就是你的段错误的来源。

相反,您的CSingleLinkedList析构函数本身需要是一个delete语句:

CSingleLinkedList::~CSingleLinkedList()
{
std::cout << "In Destructor" << std::endl;
delete head_;
}

但是,在链表中使用递归析构函数从来都不是一个好主意,尤其是在列表具有大量节点的情况下。 这可能会导致堆栈溢出,因为对CSingleLinkedNode析构函数的每个递归调用都会将越来越多的数据推送到调用堆栈上,直到到达列表末尾或调用堆栈空间不足。

在处理链表中的节点时,始终使用迭代循环 - 就像您的CSingleLinkedList析构函数尝试的那样。 为了使该循环正常工作,您需要从CSingleLinkedNode析构函数中删除delete next_;语句。 节点没有破坏其他节点的业务。 这是其父列表类的责任来管理。

相关文章:
  • 没有找到相关文章