ADi*_*ame 2 c++ linked-list segmentation-fault singly-linked-list
我正在用 C++ 编写一个单向链表,当我的单向链表的析构函数在一个包含多个节点的列表上被调用时,它会导致段错误。
我正在我的链表类上运行测试以确保它正常运行,并且在测试 PushFront 方法时遇到了问题。当我delete list从测试函数中删除该行时,我意识到析构函数导致了段错误,并且它在没有段错误的情况下运行良好(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;
}
}
Run Code Online (Sandbox Code Playgroud)
这是链接节点的析构函数(它只有数据成员 value_(一个 int)和 next_(指向下一个 CSingleLinkedNode 的指针):
// CSingleLinkedNode Destructor
CSingleLinkedList::CSingleLinkedNode::~CSingleLinkedNode()
{
delete next_;
}
Run Code Online (Sandbox Code Playgroud)
这是我正在运行以测试 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;
}
Run Code Online (Sandbox Code Playgroud)
这是我运行该函数时看到的跟踪:
TestListPushFront Passed!
In Destructor
temp = 0x55ce050332e0
toDelete = 0x55ce050332e0
temp = 0x55ce050332c0
toDelete = 0x55ce050332c0
temp = 0x55ce050332a0
Segmentation fault
Run Code Online (Sandbox Code Playgroud)
任何人都知道为什么会发生此段错误?
您的CSingleLinkedNode析构函数具有以下语句:
delete next_;
Run Code Online (Sandbox Code Playgroud)
只要您的CSingleLinkedList类delete的节点,该节点和所有后续节点都被释放,因为您正在调用递归破坏。
因此,当您的CSingleLinkedList析构函数销毁head_节点然后尝试访问下一个节点时,它会崩溃,因为下一个节点已经被销毁。这就是您的段错误的来源。
相反,您的CSingleLinkedList析构函数本身需要是一条delete语句:
CSingleLinkedList::~CSingleLinkedList()
{
std::cout << "In Destructor" << std::endl;
delete head_;
}
Run Code Online (Sandbox Code Playgroud)
然而,在链表中使用递归析构函数从来都不是一个好主意,尤其是当链表有大量节点时。这很可能会导致堆栈溢出,因为对CSingleLinkedNode析构函数的每次递归调用都会将越来越多的数据压入调用堆栈,直到到达列表末尾,或者调用堆栈空间用完为止。
在处理链表中的节点时始终使用迭代循环 - 就像您的CSingleLinkedList析构函数试图做的那样。为了使该循环正常工作,您需要delete next_;从CSingleLinkedNode析构函数中删除该语句。节点无权破坏其他节点。那是他们的父列表类的责任来管理。
| 归档时间: |
|
| 查看次数: |
46 次 |
| 最近记录: |