【发布时间】:2017-11-12 04:36:15
【问题描述】:
对于我不能使用 STL 列表的作业,它必须是自定义列表。正如标题所述,即使我在节点\项目上调用删除,我也有内存泄漏。我将不胜感激。
列出来源
template <typename T>
class DLinkList
{
private:
struct Node
{
T data;
Node *nextNode;
Node *prevNode;
Node(T data, Node *nextNode = nullptr, Node *prevNode = nullptr)
{
this->data = data;
this->nextNode = nextNode;
this->prevNode = prevNode;
}
~Node() { delete data; }
};
Node *head;
Node *tail;
public:
DLinkList();
~DLinkList();
void push_back(T data);
};
template <typename T>
inline void DLinkList<T>::push_back(T data)
{
if (isEmpty())
{
head = new Node(data);
tail = head;
}
else
{
tail->nextNode = new Node(data, nullptr, tail);
tail = tail->nextNode;
}
}
template <typename T>
DLinkList<T>::DLinkList()
{
head = nullptr;
tail = nullptr;
}
template <typename T>
DLinkList<T>::~DLinkList()
{
Node *ptr = head;
while (ptr->nextNode != nullptr)
{
Node *garbage = ptr;
ptr = ptr->nextNode;
delete garbage;
}
}
Foo 类和 main
class Foo
{
public:
Foo() { i = 0; d = 0.0; }
Foo(int i, double d) { this->i = i; this->d = d; }
int getInteger() { return i; }
double getDouble() { return d; }
private:
int i;
double d;
};
int main()
{
DLinkList<Foo*> f1;
f1.push_back(new Foo());
f1.push_back(new Foo(2, 5.5));
cout << "1st Values: " << f1.at(0)->getInteger() << ", " << f1.at(0)->getDouble() << endl;
cout << "2nd Values: " << f1.at(1)->getInteger() << ", " << f1.at(1)->getDouble() << endl;
return 0;
}
来自 valgrind
==12125== 40 (24 direct, 16 indirect) bytes in 1 blocks are definitely lost in loss record 3 of 3
==12125== at 0x4C29203: operator new(unsigned long) (vg_replace_malloc.c:334)
==12125== by 0x400FD8: DLinkList<Foo*>::push_back(Foo*) (DLinkList.hpp:138)
==12125== by 0x400CF3: main (Source.cpp:28)
我不确定这里的记忆是如何丢失的,我想说这是因为它正在复制它而原始的正在丢失。如果是这种情况,我不知道如何处理。
再次感谢任何有助于理解这一点的帮助。我试图查看所有相关问题,但我没有看到任何涵盖此内容的内容,或者至少我不理解它。谢谢!
【问题讨论】:
-
我的猜测是,这取决于您为
T使用的类型。也许Node中的析构函数会有所帮助。 -
我刚试过。调用数据删除,valgrind 显示 4 个分配,4 个释放 - 但我仍然有相同消息的泄漏。
-
@MasonR
f1.~DLinkList();-- 你为什么要这样做?一旦对象超出范围,就会自动调用对象的析构函数。您在这里所做的只是通过干扰 C++ 析构函数的工作方式而导致内存损坏。摆脱那条线,并修复你的类,使其具有正确的复制语义(只需将DLinkList分配给另一个DLInkList,你的程序就很容易被破坏)。 -
@PaulMcKenzie 我删除了这条线,我知道它是自动的。至于使类可复制,如何解决这里的内存泄漏问题?
-
一旦您执行以下操作,您将再次遇到内存泄漏和双重释放问题:
DLinkList<foo*> f2 = f1;在您填充f1之后。其次,删除该行可能无法纠正所有内存泄漏,但确实解决了通过像这样显式调用析构函数而导致的内存损坏问题。
标签: c++ list memory-leaks valgrind