我正在为我的数据结构和算法类进行 CS 分配,以实现地址结构的单链表。作业已经评分,所以我没有通过寻求帮助作弊,我在作业中得到了 80 分,因为一切正常,但我在每个节点都产生了内存泄漏。
我的 valgrind 输出的摘录如下所示:
--51-- REDIR: 0x4b4f460 (libc.so.6:free) redirected to 0x484b210 (free)
==51== Invalid read of size 8
==51== at 0x10D7A0: AddressLinkedList::~AddressLinkedList() (AddressLinkedList.cpp:31)
==51== by 0x10EA69: main (main.cpp:106)
==51== Address 0x507c1a8 is 200 bytes inside a block of size 208 free'd
==51== at 0x484BB6F: operator delete(void*, unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==51== by 0x10D7C8: AddressLinkedList::~AddressLinkedList() (AddressLinkedList.cpp:32)
==51== by 0x10EA69: main (main.cpp:106)
==51== Block was alloc'd at
==51== at 0x4849013: operator new(unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==51== by 0x10D8D6: AddressLinkedList::insertEnd(Address const&) (AddressLinkedList.cpp:53)
==51== by 0x10E701: main (main.cpp:71)
我的收获是我的链表析构函数有问题。这也是一个 8 字节的无效读取,这向我暗示有一个 64 位指针在它被取消分配后被读取,或者我忘记删除一个指针。
参考这里是我从 AddressLinkedList.cpp 的相关代码:
AddressLinkedList::AddressLinkedList() {
head = nullptr;
tail = nullptr;
length = 0;
}
AddressListNode::AddressListNode() {
next = nullptr;
//data will be default initialized
}
AddressListNode::AddressListNode(const Address& value)
: data(value)
{
next = nullptr;
}
AddressLinkedList::~AddressLinkedList() {
AddressListNode* current = head;
while (current != nullptr) {
AddressListNode* next = current->next;
delete current;
current = next;
}
head = nullptr;
tail = nullptr;
length = 0;
}
void AddressLinkedList::insertEnd(const Address& value){
AddressListNode* newTail = new AddressListNode(value);
if (head == nullptr){
head = newTail;
tail = newTail;
} else{
tail->next = newTail;
tail = newTail;
}
length++;
}
我知道这一定是一个愚蠢的、容易避免的问题,但我根本看不到我在哪里产生泄漏。也许我需要在删除节点之前清空节点内的数据?我只是删除指向节点的指针而不是节点本身吗?
我已经尝试了在 stackoverflow 上找到的各种析构函数,我已经问过 ChatGPT 我的代码有什么问题,但我没有得到任何东西来阻止 valgrind 错误。理想情况下,链表应该很好地自行清理,但我的实现导致了太多错误,以至于 valgrind 停止报告它们。