C++ 如何防止广义链表中的内存泄漏?

C++ 如何防止广义链表中的内存泄漏?,c++,pointers,memory,memory-leaks,linked-list,C++,Pointers,Memory,Memory Leaks,Linked List,我已经实现了自己的链表数据结构。数据存储在节点结构中。代码如下 // NODE template <typename T> struct Node { T data; Node<T> *next; Node(T); }; template <typename T> Node<T>::Node(T d) : data(d), next(NULL) {} 根据Valgrind,该程序存在内存泄漏。这是因为节点没有析构函数,

我已经实现了自己的链表数据结构。数据存储在
节点
结构中。代码如下

// NODE

template <typename T>
struct Node
{
    T data;
    Node<T> *next;
    Node(T);
};

template <typename T>
Node<T>::Node(T d) : data(d), next(NULL) {}

根据Valgrind,该程序存在内存泄漏。这是因为
节点
没有析构函数,因此无法删除其中的
数据。但是,我无法将析构函数添加到
节点
,因为假设我正在使用
列表
,因此删除未动态分配的内容是错误的。简而言之,每当我为
列表
使用动态分配的数据类型时,就会出现内存泄漏。我怎样才能克服这种情况?谢谢

使用
std::unique_ptr
作为节点的数据类型,例如:

列表l


当每个节点被销毁时,它的析构函数将销毁它的
唯一的\u ptr
数据,这将依次调用它所持有的
int*
指针上的
delete[]

示例中的泄漏与列表无关。您可以通过以下方式进行泄漏:

void func()
{
    int *i = new int[2];
    i[0] = 1;
    i[1] = 2;
}
您必须
删除
通过
新建创建的内容
删除[]
通过
新建[]
创建的内容。要修复泄漏,请执行以下操作:

void func()
{
    int *i = new int[2];
    i[0] = 1;
    i[1] = 2;
    l.push_back(i);
    delete [] i;
}
但是,请注意,在
delete[]
之后,列表中有一个悬空指针

当您将原始指针推送到
列表时,删除对象不是
列表的职责。列表无法知道它们是否拥有指针。例如:

void func()
{
    int i = 0;
    l.push_back(&i);
}
无需在此处删除任何内容。(不过,这里也一样:一旦函数返回,列表中就有一个悬空指针)


这两个字母都不是真的“ok”。不要使用原始指针!使用智能指针代替。如果需要整数列表,则使用
列表(或者更确切地说是
std::list
)。

如果对象有需要释放的分配,则需要添加析构函数。这不是可选的。被列入“名单”并不能免除你的责任。这里的一个解决方案是使用一个可以为您处理它的列表,这样列表就不需要了。“如何防止通用链表中的内存泄漏?”-不滚动您自己的,而是使用
std::List
。Imho,您的列表不应该释放此指针<代码>标准::列表
不会。另外,您的类违反了。在责怪您的实现之前,我会仔细检查
std::list
。也就是说,在将
l
的声明更改为
std::list l之后运行测试。当它泄漏的内存与您的实现一样多时,您有理由怀疑问题在于列表的使用方式,而不是列表的实现方式。(请注意,我写的是“可疑”,而不是“知道”。称之为80%左右的保证率,从空中提取一个数字。)
void func()
{
    int *i = new int[2];
    i[0] = 1;
    i[1] = 2;
    l.push_back(i);
    delete [] i;
}
void func()
{
    int i = 0;
    l.push_back(&i);
}