VS2017下链表insertAtEnd二次调用崩溃:空指针异常排查
解决insertAtEnd第二次调用时的空指针崩溃问题
我来帮你分析并搞定这个崩溃问题——你遇到的情况完全是因为insertAtEnd函数里的遍历逻辑写错了,导致指针变成NULL后还硬去调用成员函数。
问题根源
先看你代码里的这个while循环:
while (temp2->getNext() != NULL || temp2->getData()!=value) { temp2 = temp2->getNext(); }
这个条件用了||(逻辑或),这就是核心bug:
当第二次插入"love"时,链表只有一个节点(data是"i",next为NULL)。此时temp2->getNext() != NULL是false,但temp2->getData() != value是true,所以整个条件为true,循环继续执行temp2 = temp2->getNext();,这时候temp2就变成了NULL。
循环结束后,你又去调用temp2->getData(),对空指针调用成员函数,直接触发崩溃,这就是调试时提示getNext()返回NULL的本质原因(其实是temp2本身已经是NULL了)。
修复方案
正确的逻辑应该拆成两步:先遍历链表检查是否已有相同value的节点,如果有就直接添加detail;如果没有,再把新节点加到链表末尾。这样逻辑清晰,不会出错:
修改后的insertAtEnd函数代码:
void list::insertAtEnd(string value, int lin) { // 第一步:检查链表中是否已有相同value的节点 node* current = head; while (current != nullptr) { if (current->getData() == value) { current->setDetail(lin); return; // 找到匹配节点,处理后直接返回 } current = current->getNext(); } // 第二步:如果没有找到,创建新节点并添加到链表末尾 node* newNode = new node(value); newNode->createDetail(); newNode->setDetail(lin); if (head == nullptr) { // 链表为空,直接作为头节点 head = newNode; } else { // 找到链表的最后一个节点 node* tail = head; while (tail->getNext() != nullptr) { tail = tail->getNext(); } tail->setNext(newNode); } }
为什么这样改?
- 拆分逻辑后更清晰:先找已有节点,再处理新增,避免了原来把两个判断混在一个循环里的混乱。
- 遍历末尾节点时,循环条件只判断
tail->getNext() != nullptr,确保tail始终是有效的节点,不会变成NULL。 - 一旦找到匹配节点就直接返回,不需要继续遍历,效率也更高。
现在你再运行a.insertAtEnd("i", 1); a.insertAtEnd("love", 1);就不会崩溃了,第二次插入会正常把"love"节点加到链表末尾。
内容的提问来源于stack exchange,提问作者abdullah
相关产品推荐
相关产品推荐

