C++ 链表分段错误和 valgrind 错误

时间:2021-05-26 20:37:44

标签: c++ valgrind

我需要用 C++ 为大学编写一个链表,主要是为了练习编码迭代器。 我用一些基本情况对其进行了测试,它可以工作,但是在我通过 valgrind 和程序的测试服务器后,我得到了不同错误的列表。也许有人可以帮助我不要绝望。 (最后我会附加错误列表)

template <typename T = float>
class ForwardList
{
 
    struct Node
    {
        /// Constructs a Node from a data value and a link to the next element.
        Node(const T &data, Node *next) : data{data}, next{next} {}

        /// A Node owns all nodes after it, so it deletes them on destruction
        ~Node() { delete next; }

        
    //Performs a deep copy of the Node and all Nodes after it. Bad practice but we got it like that
        Node *clone() const
        {
            if (next == nullptr)
            {
                return new Node{data, nullptr};
            }
            else
            {
                return new Node{data, next->clone()};
            }
        }

        T data;
        Node *next;
    };

public:

    ForwardList() : head(nullptr) {}

    /// Copy constructor performs a deep copy of the other list's Nodes
    ForwardList(const ForwardList &other)
    {
        head = other.head->clone();
    }

    /// Destructor makes sure that all Nodes are correctly destroyed
    ~ForwardList()
    {
        while (head->next != nullptr)
        {
            Node *tmp = head;
            head = head->next;
            delete tmp;
        }
        delete head;
    }

    /// Copy assignment operator uses the copy-and-swap idiom to make a safe
    /// assignment
    ForwardList &operator=(ForwardList other)
    {
        swap(*this, other);
        return *this;
    }

   
    /// Add an element to the front of the list.
    void push_front(const T &value)
    {   
        std::cout << "Num: " << numberOfNodes << std::endl;

        Node *item = new Node(value, nullptr);
        if (head==nullptr)
        {
            head = item;
        }else
        {
            item->next=head;
            head = item;
        }
         numberOfNodes++;
    }

    /// Remove the first element of the list. Calling this function on an empty
    /// list is undefined behavior. When implementing this function, be careful
    /// to delete the one and only the one element that is removed.
    void pop_front()
    {
        Node *item;
        item = head->next;
        delete head;
        head = item;
        numberOfNodes--;
    }

    /// Get a reference to the first element of the list
    /// (const and non-const version)
    T &front()
    {
        return head->data;
    }
    const T &front() const
    {
        return head->data;
    }

    /// Return true is the list is empty
    bool empty() const
    {
        return numberOfNodes == 0 ? true : false;
    }
    std::size_t size() const
    {
        return numberOfNodes;
    }

    friend void swap(ForwardList &l, ForwardList &r)
    {
        Node *tmp = l.head;
        l.head = r.head;
        r.head = tmp;
    }

private:
    Node *head;
    size_t numberOfNodes = 0;
};

现在是有趣的部分(我会把它放在 pastebin 上,因为它很长): https://pastebin.com/4JAKkJtP

1 个答案:

答案 0 :(得分:2)

您的问题是 ~Node 尝试删除其 next,并且您还尝试遍历 ~ForwardList 中的列表。通过删除 ~Node(),您让 ForwardList 处理清理并且一切正常。

这里的线索是 valgrind 在释放后报告了使用,这意味着某些东西删除了两次指针。这是查看所有删除 Node*(或实际上,通常为 delete)的线索的线索。

相关问题