调试C++链表两数相加程序:为何l3=l3->next会触发空指针错误?
问题分析与解决方案
这个空指针错误的原因很明确:你在执行l3 = l3->next;的时候,l3本身已经是NULL了,这时候去访问它的next成员,必然会触发内存访问错误。
为什么会出现这种情况?
通常是因为你在构建结果链表时,没有正确处理初始空指针或者遍历结束后的边界情况:
- 如果你没有用「哑节点(dummy node)」来初始化结果链表,而是直接让
l3作为头节点,初始值为NULL,那第一次循环里尝试访问l3->next自然会出错——空指针根本没有next成员。 - 另一种可能是,当两个输入链表都遍历完之后,还有进位需要添加一个新节点,但你没有创建这个节点,就直接执行了
l3 = l3->next;,导致l3变成NULL后继续操作。
正确的实现思路(附代码示例)
解决这类链表问题的通用技巧是用哑节点来简化头节点的处理,它是一个占位的空节点,永远不会为空,这样你就不用操心初始时头节点为空的情况。
这里是修正后的完整代码:
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { // 创建哑节点,作为结果链表的占位头 ListNode* dummy = new ListNode(0); // curr用来跟踪当前结果链表的最后一个节点 ListNode* curr = dummy; int carry = 0; // 循环条件:只要还有未处理的节点,或者还有进位 while (l1 != nullptr || l2 != nullptr || carry != 0) { int sum = carry; // 累加l1当前节点的值(如果l1还没遍历完) if (l1 != nullptr) { sum += l1->val; l1 = l1->next; } // 累加l2当前节点的值(如果l2还没遍历完) if (l2 != nullptr) { sum += l2->val; l2 = l2->next; } // 计算进位和当前位的值 carry = sum / 10; int currentVal = sum % 10; // 创建新节点并添加到结果链表末尾 curr->next = new ListNode(currentVal); // 移动curr到新节点 curr = curr->next; } // 哑节点的next才是真正的结果链表头 return dummy->next; } };
关键细节说明
- 哑节点的作用:它避免了我们需要单独处理「结果链表为空」的情况,初始时
curr指向哑节点,永远不会是NULL,所以访问curr->next是安全的。 - 循环条件:必须包含
carry != 0,否则当两个链表都遍历完但还有进位时(比如999+1=1000),会漏掉最后一个进位节点。 - 指针移动时机:只有在创建了新节点之后,才移动
curr到curr->next,保证curr始终指向一个有效的节点。
你可以对比自己的代码,看看是不是在上述某个环节出了问题——比如没有用哑节点,或者循环条件没考虑进位,导致l3提前变成NULL后还去访问它的next。
内容的提问来源于stack exchange,提问作者ukp
相关产品推荐
相关产品推荐

