C++ 重载双向链表-=运算符实现差集触发段错误问题求助
问题原因分析
- 核心错误1:
-=运算符遍历链表删除节点后访问野指针
你在嵌套循环里匹配到节点直接调用removeByNode(temp1)删除temp1,但后续循环仍然执行temp1 = temp1->get_next(),此时temp1已经被释放属于野指针,访问直接触发段错误。 - 核心错误2:
removeByNode未处理边界节点
该函数没有判断要删除的节点是头节点/尾节点的场景:如果删除头节点,current->get_prev()返回NULL,调用NULL->set_next()直接段错误;删除尾节点同理current->get_next()返回NULL,调用NULL->set_prev()也会崩溃。 - 衍生错误:
removeFromHead、removeFromTail逻辑存在空指针风险
这两个函数先访问head->get_next()/tail->get_prev()再判断head/tail是否为空,空链表调用时会直接访问空指针触发崩溃,且删除最后一个节点后没有同步置空头尾指针。
修复方案
1. 修复removeByNode函数
void LinkedList::removeByNode(Node* c) { if (c == NULL) return; // 空指针直接返回 // 处理前驱节点 if (c->get_prev() != NULL) { c->get_prev()->set_next(c->get_next()); } else { // 要删的是头节点,更新头指针 head = c->get_next(); } // 处理后继节点 if (c->get_next() != NULL) { c->get_next()->set_prev(c->get_prev()); } else { // 要删的是尾节点,更新尾指针 tail = c->get_prev(); } delete c; current = head; }
2. 修复-=运算符逻辑
删除节点前先暂存下一个节点的地址,避免访问野指针:
LinkedList LinkedList::operator -= (const LinkedList& LL2) { Node* temp2; // 遍历LL2的所有元素 for (temp2 = LL2.head; temp2 != NULL; temp2 = temp2->get_next()) { Node* temp1 = head; // 遍历当前链表匹配元素 while (temp1 != NULL) { Node* next_node = temp1->get_next(); // 先存下一个节点 if (temp1->get_data() == temp2->get_data()) { removeByNode(temp1); } temp1 = next_node; // 用暂存的地址移动指针 } } return *this; }
3. 可选修复:完善removeFromHead、removeFromTail逻辑
void LinkedList::removeFromHead() { if (head == NULL) return; // 空链表直接返回 Node* temp = head->get_next(); delete head; head = temp; if (head == NULL) { tail = NULL; // 删完为空,同步置空尾指针 } else { head->set_prev(NULL); } } void LinkedList::removeFromTail() { if (tail == NULL) return; // 空链表直接返回 Node* temp = tail->get_prev(); delete tail; tail = temp; if (tail == NULL) { head = NULL; // 删完为空,同步置空头指针 } else { tail->set_next(NULL); } }
内容的提问来源于stack exchange,提问作者Daniel Dinosaur
相关产品推荐
相关产品推荐

