我找不到瓦尔格林德告诉我的记忆链接



我正在编写一个链表,以及一个将新值附加到其中的函数,这是我的代码:

#include <iostream>
using namespace std;
struct ListNode {
int m_value;
ListNode *m_next;
ListNode () {}
ListNode(int i) {
m_value = i;
m_next = NULL;
}
};
void append(int const value, ListNode *head) {
ListNode *list = new ListNode(value);
if (head != NULL) {
while (head->m_next != NULL) {
head = head->m_next;
}
head->m_next = list;
} else {
head = list;
}
}
void print(ListNode *head) {
while (head != NULL) {
cout << head->m_value << endl;
head = head->m_next;
}
}
int main() {
ListNode *list = new ListNode(1);
append(2, list);
append(3, list);
append(4, list);
append(5, list);
print(list);
delete list;
}

然后我用 valgrind 检查内存泄漏,使用以下命令:

valgrind --leak-check=full --show-reachable=yes --trace-children=yes ./listnodes 

它显示:

64 (16 direct, 48 indirect) bytes in 1 blocks are definitely lost in loss record 4 of 4
at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x108B1D: append(int, ListNode*) (in /home/qihao/c/test/listnodes/listnodes/listnodes)
by 0x108968: main (in /home/qihao/c/test/listnodes/listnodes/listnodes)
LEAK SUMMARY:
definitely lost: 16 bytes in 1 blocks
indirectly lost: 48 bytes in 3 blocks
possibly lost: 0 bytes in 0 blocks
still reachable: 0 bytes in 0 blocks
suppressed: 0 bytes in 0 blocks
ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

有一个泄漏。我无法知道泄漏发生在我的代码中的位置,有人可以帮忙吗?谢谢。

因为你只删除列表的头部。每次调用append函数时,都会创建一个新节点。在程序结束时,您必须删除所有节点,请尝试执行以下操作:

int main()
{
ListNode *list = new ListNode(1);
append(2, list);
append(3, list);
append(4, list);
append(5, list);
print(list);
ListNode *tmp1 = list;
ListNode *tmp2;
while (tmp1 != NULL)
{
tmp2 = tmp1->m_next;
delete tmp1;
tmp1 = tmp2;
}
}

R.11:避免调用new并显式删除。使用智能指针。appendnew.您不会删除这些对象并释放内存。这就是内存泄漏。

我将您的代码从使用原始指针更改为使用智能指针

#include <iostream>
#include <memory>
struct ListNode {
int m_value;
std::unique_ptr<ListNode> m_next;
ListNode () = default;
ListNode(int i) : m_value(i) {}
};
void append(int const value, ListNode *head) {
if (head != nullptr) {
while (head->m_next != nullptr) {
head = head->m_next.get();
}
head->m_next = std::make_unique<ListNode>(value);
}
}
void print(ListNode *head) {
while (head != nullptr) {
std::cout << head->m_value << 'n';
head = head->m_next.get();
}
}
int main() {
auto list = std::make_unique<ListNode>(1);
append(2, list.get());
append(3, list.get());
append(4, list.get());
append(5, list.get());
print(list.get());
}

功能应该是相同的,但现在您不必担心清理内存。您应该注意,在此代码的两个版本中head

void append(int const value, ListNode *head)

必须指向有效的ListNode对象。否则,列表将保持为空。

您可以使用对head的引用来解决此问题

#include <iostream>
#include <memory>
struct ListNode {
int m_value;
std::unique_ptr<ListNode> m_next;
ListNode () = default;
ListNode(int i) : m_value(i) {}
};
void append(int const value, std::unique_ptr<ListNode> &head) {
if (!head) {
head = std::make_unique<ListNode>(value);
return;
}
auto temp = head.get();
while (temp->m_next != nullptr) {
temp = temp->m_next.get();
}
temp->m_next = std::make_unique<ListNode>(value);
}
void print(ListNode *head) {
while (head != nullptr) {
std::cout << head->m_value << 'n';
head = head->m_next.get();
}
}
int main() {
//auto list = std::make_unique<ListNode>(1);
std::unique_ptr<ListNode> list;
append(2, list);
append(3, list);
append(4, list);
append(5, list);
print(list.get());
}

这是不相关的,但我建议阅读我应该在我的代码中使用命名空间 std 吗?

相关内容

最新更新