单链表已做非空检查仍触发nullptr错误,求原因解析
单链表空指针检查问题解析
在使用单链表时,有人建议我使用“if x != nullptr”进行检查,但我不理解其作用。我的示例代码中,前两个打印语句可正常运行,但添加第三个打印语句后就会触发nullptr错误,尽管前一行刚完成节点非空检查且执行成功。
示例代码:
ListNode* addTwoNumbers(ListNode* l1) { // l1包含3个存储单个数字的节点 std::cout << l1->val; l1 = l1->next; if (l1 != nullptr) { std::cout << l1->val; } std::cout << l1->val; return 0; }
空指针检查到底有啥用?
单链表的最后一个节点的next指针会指向nullptr,代表链表到此结束。如果直接访问nullptr的成员(比如->val),会触发程序崩溃(属于未定义行为)。if(x != nullptr)就是用来在访问节点前,确认当前指针不是空的,避免这种崩溃。
你的代码为啥会报错?
按你说的链表有3个节点(node1 -> node2 -> node3 -> nullptr),走一遍代码逻辑:
- 第一行打印
node1的值,l1移动到node2; if判断l1非空,打印node2的值;- 第三行直接打印
l1->val——这时候l1还是node2,理论上不会报错。
但你说加了第三个打印就崩溃,说明执行到第三行时l1已经是nullptr,大概率是这两种情况:
- 链表结构理解错了:实际你的链表只有2个节点(
node1 -> node2 -> nullptr),且你在if块之后不小心多写了一行l1 = l1->next,让l1变成了nullptr; - 代码逻辑写错了:比如在
if块里加了l1 = l1->next,让l1移动到node3的next(也就是nullptr),之后访问自然崩溃。
安全遍历链表的正确写法
如果要打印所有节点值,最稳妥的是用循环+空指针检查:
ListNode* addTwoNumbers(ListNode* l1) { while (l1 != nullptr) { std::cout << l1->val; l1 = l1->next; } return nullptr; }
如果要逐个处理固定数量的节点,也要每次访问前检查:
ListNode* addTwoNumbers(ListNode* l1) { // 处理第一个节点 if (l1 != nullptr) { std::cout << l1->val; l1 = l1->next; } // 处理第二个节点 if (l1 != nullptr) { std::cout << l1->val; l1 = l1->next; } // 处理第三个节点 if (l1 != nullptr) { std::cout << l1->val; } return nullptr; }
这样不管链表实际有几个节点,都不会触发空指针错误。
内容的提问来源于stack exchange,提问作者Tenacity
相关产品推荐
相关产品推荐

