C++为什么会导致内存泄漏?
如果我们有以下简单的双链接列表:C++为什么会导致内存泄漏?,c++,memory-leaks,linked-list,doubly-linked-list,C++,Memory Leaks,Linked List,Doubly Linked List,如果我们有以下简单的双链接列表: class Node{ //... Node* next; Node* previous; int data; }; class A{ //... A(const A&); ~A(); //goes through list and deletes each node A& operator=(const A&); Node* begin; Node*
class Node{
//...
Node* next;
Node* previous;
int data;
};
class A{
//...
A(const A&);
~A(); //goes through list and deletes each node
A& operator=(const A&);
Node* begin;
Node* end;
int id;
};
A::A(const A& copyThis)
{
//creates a new list that represnets the same data as copyThis's list
//but is not the same list
//Example for clarification:
//if copyThis represented a list of nodes each containing the values 1-10 respectively
//this constructor would make a new list of nodes each containing the values 1-10
//and make the invoking object's members point to the beginning and end of it
//assume this does not create any memory leaks
}
A& A::operator=(const A& a) //this causes a memory leak
{
A* aCopy = new A(a); //now 'a' and 'this' should represent the same
//values but point to different lists
this->begin = aCopy->begin;
this->end = aCopy->end;
this->id = aCopy->id;
//code here that deletes list that invoking object used to point to
//assume it does correctly and without memory leak
return *this;
}
假设我们有这个函数:
void foo()
{
A a1();
//put some data into a1
A a2();
{a2=a1;}
}
我的问题是,为什么这会导致内存泄漏,因为a2应该表示aCopy在operator=内部执行的相同节点列表,并且当a2超出范围时,它会正确释放为每个节点分配的内存
编辑:
好的,我在发布这个问题几分钟后才意识到,也许创建一个新的副本会为它所代表的节点分配更多的内存,而且内存永远不会被释放。这是正确的吗
编辑:
我并不是要用更好或正确的方法来编写这段代码,我只是想解释一下为什么这会导致内存泄漏。首先,operator=需要返回T&。你正在泄漏aCopy指向的内存。你根本不需要这个。你应该这样做:
A& A::operator=(const A& a)
{
this->begin = a.begin;
//etc.
return *this;
}
为什么不使用智能指针?为什么要创建副本?@Nostradamus我只是想了解在这种情况下导致泄漏的原因,我知道有很多其他方法可以有效地避免内存泄漏。当时,我觉得这段代码不应该导致内存泄漏。没错,你正在分配一个不删除的新内存空间。为什么要使用指针?除非你真的需要,否则不要使用指针。传递值,std::move负责不创建临时副本。何时是使用指针的适当时间?当您使用一个无法更改且没有重载移动构造函数和/或赋值运算符的库时,您需要这些对象的集合。即使这样,您也应该使用智能指针而不是原始指针。operator=不一定需要返回t&。这种方法的危险在于现在您有一个和这个指针在同一个开始和结束处。这可能会很糟糕。请更改op以返回一个&@user4581301 correct,这就是为什么我没有采用这种方法。请记住,我知道更好的方法,只是想知道为什么这会导致泄漏。@MikeRizzle这很好,但我留下了面包屑。一些不太了解情况的读者可能会看到上述答案,并浪费数小时进行调试。