【问题标题】:C++ Why does this cause a memory leak? [duplicate]C++ 为什么这会导致内存泄漏? [复制]
【发布时间】:2015-11-19 21:23:28
【问题描述】:

如果我们有以下简单的双链表:

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 应该代表与aCopyoperator= 内部相同的Nodes 列表,并且当a2 超出范围时,它会释放分配的内存正确地为每个节点。

编辑: 好的,所以我在发布这个问题几分钟后才意识到,也许用new 创建aCopy 分配的内存不仅仅是它所代表的Nodes,而且内存永远不会被释放。这是正确的吗?

编辑: 我不是要求更好或更正确的方法来编写此代码,我只是要求解释为什么这会导致内存泄漏。

【问题讨论】:

  • 为什么不使用智能指针?
  • 为什么要创建aCopy
  • @Nostradamus 我只是想了解在这种情况下导致泄漏的原因,我知道还有许多其他方法可以有效地做到这一点而不会发生内存泄漏。当时,在我看来,这段代码不应该导致内存泄漏。
  • 没错,你正在分配一个你不删除的新内存空间
  • 为什么要使用指针? 不要使用指针,除非你真的必须这样做。按值传递,std::move 负责不创建临时副本。什么时候使用指针合适?当您使用无法更改且没有重载移动构造函数和/或赋值运算符的库时,您需要这些对象的集合。即使这样,您也应该使用智能指针而不是原始指针。

标签: c++ memory-leaks linked-list doubly-linked-list


【解决方案1】:

一方面,operator= 需要返回 T&。您正在泄漏 aCopy 指向的内存。你根本不需要那个。你应该这样做:

A& A::operator=(const A& a)
{
    this->begin = a.begin;
    //etc.
    return *this;
}

【讨论】:

  • operator= 不一定需要返回T&
  • 这种方法的危险现在你有athis指向同一个beginend。这可能会以糟糕的方式结束。
  • 更改 op 以返回 A&
  • @user4581301 正确,这就是我没有采用这种方法的原因。请记住,我知道更好的方法只是想知道为什么会导致泄漏。
  • @MikeRizzle 这很好,但我要留下面包屑了。一些不太了解的读者可能会看到上面的答案并浪费时间调试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-03
  • 2011-06-25
  • 2022-06-10
  • 2022-01-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多