我需要用 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
答案 0 :(得分:2)
您的问题是 ~Node
尝试删除其 next
,并且您还尝试遍历 ~ForwardList
中的列表。通过删除 ~Node()
,您让 ForwardList
处理清理并且一切正常。
这里的线索是 valgrind
在释放后报告了使用,这意味着某些东西删除了两次指针。这是查看所有删除 Node*
(或实际上,通常为 delete
)的线索的线索。