C++ 我能';我找不到valgrind告诉我的记忆链接

C++ 我能';我找不到valgrind告诉我的记忆链接,c++,C++,我正在编写一个链表,以及一个向其中添加新值的函数,下面是我的代码: #包括 使用名称空间std; 结构列表节点{ int m_值; ListNode*m_next; ListNode(){} 列表节点(int i){ m_值=i; m_next=NULL; } }; void append(int const值,ListNode*head){ ListNode*list=新ListNode(值); if(head!=NULL){ while(head->m_next!=NULL){ head=h

我正在编写一个链表,以及一个向其中添加新值的函数,下面是我的代码:

#包括
使用名称空间std;
结构列表节点{
int m_值;
ListNode*m_next;
ListNode(){}
列表节点(int i){
m_值=i;
m_next=NULL;
}
};
void append(int const值,ListNode*head){
ListNode*list=新ListNode(值);
if(head!=NULL){
while(head->m_next!=NULL){
head=head->m_next;
}
head->m_next=列表;
}否则{
head=列表;
}
}
无效打印(列表节点*头){
while(head!=NULL){
cout m_value m_next;
}
}
int main(){
ListNode*list=新的ListNode(1);
附加(2,列表);
附加(3,列表);
附加(4,列表);
附加(5,列表);
打印(列表);
删除名单;
}
然后我使用valgrind检查内存泄漏,使用以下命令:

valgrind--leak check=full--show reachable=yes--trace children=yes./listnodes
它表明:

1个块中的64(16个直接字节,48个间接字节)字节肯定会在丢失记录4(共4个)中丢失
在0x4C3017F处:运算符新(未签名长)(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so中)
通过0x108B1D:append(int,ListNode*)(in/home/qihao/c/test/listnodes/listnodes/listnodes)
按0x108968:main(in/home/qihao/c/test/listnodes/listnodes/listnodes)
泄漏摘要:
绝对丢失:1个块中有16个字节
间接丢失:3个块中48字节
可能丢失:0个块中有0个字节
仍然可访问:0个块中有0个字节
抑制:0个块中有0个字节
错误摘要:1个上下文中的1个错误(已抑制:0中的0)
有一个漏洞。我不知道我的密码泄露的地方,有人能帮忙吗?谢谢。

。使用智能指针。在
append
中是一个
新的
。您不会删除这些对象并释放内存。这就是内存泄漏

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

#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());
}
必须指向有效的
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());
}
#包括
#包括
结构列表节点{
int m_值;
std::unique_ptr m_next;
ListNode()=默认值;
ListNode(inti):m_值(i){}
};
void append(int const value,std::unique_ptr&head){
如果(!头){
head=std::使_唯一(值);
返回;
}
自动温度=head.get();
while(temp->m_next!=nullptr){
temp=temp->m_next.get();
}
temp->m_next=std::使_唯一(值);
}
无效打印(列表节点*头){
while(head!=nullptr){
std::cout m_value m_next.get();
}
}
int main(){
//自动列表=标准::使_唯一(1);
std::唯一的ptr列表;
附加(2,列表);
附加(3,列表);
附加(4,列表);
附加(5,列表);
打印(list.get());
}

这是不相关的,但我建议您阅读

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

intmain()
{
ListNode*list=新的ListNode(1);
附加(2,列表);
附加(3,列表);
附加(4,列表);
附加(5,列表);
打印(列表);
ListNode*tmp1=列表;
ListNode*tmp2;
while(tmp1!=NULL)
{
tmp2=tmp1->m_next;
删除tmp1;
tmp1=tmp2;
}
}

是否使用调试信息构建(在构建时添加
-g
标志)?然后Valgrind将能够为您提供文件名和行号信息。您应该避免使用原始指针和裸
new
/
delete
。使用智能指针。在append中是一个新的
。您在哪里删除这些对象并释放内存?通常,您需要将每个
new
与相应的
delete
相匹配。如果你做了多个<代码>新的< /代码>,那么你需要多个< C++ >删除>代码>。这意味着该值被复制到函数参数变量中。修改参数变量(例如通过赋值)不会更改原始值。当您在
append
函数中分配给
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());
}