导致 Seg 错误的 SingleLinkedList 的析构函数
Destructor of a SingleLinkedList Causing a Seg Fault
我正在用 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_;
一旦你的CSingleLinkedList
类delete
节点,该节点和所有后续节点就会被释放,因为你正在调用递归破坏。
因此,当您的CSingleLinkedList
析构函数销毁head_
节点,然后尝试访问下一个节点时,它会崩溃,因为下一个节点已被销毁。 这就是你的段错误的来源。
相反,您的CSingleLinkedList
析构函数本身需要是一个delete
语句:
CSingleLinkedList::~CSingleLinkedList()
{
std::cout << "In Destructor" << std::endl;
delete head_;
}
但是,在链表中使用递归析构函数从来都不是一个好主意,尤其是在列表具有大量节点的情况下。 这可能会导致堆栈溢出,因为对CSingleLinkedNode
析构函数的每个递归调用都会将越来越多的数据推送到调用堆栈上,直到到达列表末尾或调用堆栈空间不足。
在处理链表中的节点时,始终使用迭代循环 - 就像您的CSingleLinkedList
析构函数尝试的那样。 为了使该循环正常工作,您需要从CSingleLinkedNode
析构函数中删除delete next_;
语句。 节点没有破坏其他节点的业务。 这是其父列表类的责任来管理。
- 没有找到相关文章