单链表返回错误,即使我已经检查过了

问题描述 投票:0回答:1

当使用单链表时,有人建议我使用“if x != nullptr”,但我不明白为什么这样做。在我的示例代码中,第一个和第二个打印语句有效,但是一旦我添加第三个打印语句,就会出现 nullptr 错误。尽管已经检查了之前的节点并成功运行了它。

ListNode* addTwoNumbers(ListNode* l1) { // l1 has 3 nodes containing a single digit
    std::cout << l1->val;
    l1 = l1->next;
    if (l1 != nullptr) {
        std::cout << l1->val;
    }
    std::cout << l1->val;
    return 0;
}

如果注释掉第三条打印语句,它会打印出前两个节点,但如果添加第三条,则会出错。我已经检查过 if (l1 != nullptr) 并成功运行了第二个打印语句,因此可以安全地假设 l1->val 也有效,但事实并非如此。

c++ singly-linked-list cout nullptr
1个回答
0
投票

对于生产工作,您应该使用标准库中的链表类之一。标题

<list>
(对于双链表)和
<forward_list>
(对于单链表)应该优先于任何类型的“自己动手”实现。

如果这是为了家庭作业,或者可能是某种编码挑战,你可能没有这个选择。但请注意,传递 naked

ListNode
指针并将它们视为列表是错误的做法。如果您必须推出自己的链接列表类,则应该按照标准库中的链接列表类进行建模。这意味着编写一个适当的
List
ForwardList
类来管理构成链表的
ListNodes
ListNode
结构本身应该嵌套在父
List
类中,并且您应该编写迭代器,这样您就不必使用原始指针。

这是一项相当大的工作。

然而,您可能无法选择“以正确的方式”做事。例如,LeetCode 使用裸

ListNode
指针,例如在 OP 中找到的指针。

流插入运算符<<

OP 包含输出链表的代码。该代码失败了,因为它在检查指针是否等于

nullptr
之前取消引用指针。

这是使用

operator<<
的替代公式。

// main.cpp
#include <iostream>
#include <new>
#include <stdexcept>
#include <utility>

struct ListNode
{
    int value{};
    ListNode* next{ nullptr };
    ListNode(
        int const value = 0,
        ListNode* const next = nullptr)
        : value{ value }
        , next{ next }
    {}
    static void clear(ListNode*& head) noexcept {
        while (head)
            pop_front(head);
    }
    static void pop_front(ListNode*& head) noexcept
    {
        if (head) {
            auto p{ head };
            head = head->next;
            p->next = nullptr;
            delete p;
        }
    }
    static void push_front(ListNode*& head, int const n) {
        head = new ListNode(n, head);
    }
    friend std::ostream& operator<< (std::ostream& ost, ListNode* const head)
    {
        ost.put('[');
        if (auto node{ head }; node)
            for (;;) {
                ost << node->value;
                node = node->next;
                if (!node) break;
                ost.put(',');
            }
        ost.put(']');
        return ost;
    }
};
int main()
{
    ListNode* head{ nullptr };
    ListNode::push_front(head, 1);
    ListNode::push_front(head, 2);
    ListNode::push_front(head, 3);
    std::cout << "list = " << head << '\n';
    ListNode::clear(head);  // avoid memory leaks.
}
// end file: main.cpp

输出:

list = [3,2,1]
© www.soinside.com 2019 - 2024. All rights reserved.