【问题标题】:Memory leak in assignment operator for binary search tree二叉搜索树的赋值运算符中的内存泄漏
【发布时间】:2016-05-08 00:32:44
【问题描述】:

所以我似乎无法找出我为什么会泄漏内存,有人可以帮忙吗?我用operator=:实现了一个二叉搜索树

BinTree& BinTree::operator=(const BinTree &other)
{
    if (other.root == NULL)
        root = NULL;
    else
    {
        copyHelper(root, other.root);
    }
    return *this;

}

复制助手:

void BinTree::copyHelper(Node *&current, const Node *other)
{
    if (other == NULL)
        current = NULL;
    else
    {
        current = new Node;
        current->data = other->data;
        copyHelper(current->left, other->left);
        copyHelper(current->right, other->right);
    }   
}

我知道current = new Node; 是发生泄漏的地方,但是如果我尝试在该行之前执行delete current;,我的程序就会崩溃。

这是我的析构函数:

BinTree::~BinTree()
{
    destroyRecursive(root);
}

void BinTree::destroyRecursive(Node *node)
{
    if (node)
    {
        destroyRecursive(node->left);
        destroyRecursive(node->right);
        delete node;
    }
}

【问题讨论】:

  • 那么你的Node析构函数是什么样的?注意你还需要深拷贝data,不清楚这是否发生。
  • 你没有显示一个delete,那么任何人应该如何评论潜在的泄漏?
  • @EJP 我添加了析构函数
  • @EJP 好的,但我仍然在泄漏内存

标签: c++ memory memory-leaks variable-assignment assignment-operator


【解决方案1】:

由于您使用原始指针,您必须手动删除分配的内存。将current 设置为NULL 时会发生内存泄漏

void BinTree::copyHelper(Node *&current, const Node *other)
{
    if (other == NULL)
    {
        delete current;    // w/o this line next
        current = NULL;    // will cause memory leak (if not managed somewhere else)
    }
    else
    {
        current = new Node;
        current->data = other->data;
        copyHelper(current->left, other->left);
        copyHelper(current->right, other->right);
    }   
}

【讨论】:

【解决方案2】:

糟糕的代码结构。 C++ 为您提供了执行此操作的所有便利,但您很少或根本没有利用它。需要删除当前树的root在算子函数中,然后copy-construct新节点;你需要修复你的析构函数。

  1. 递归复制助手应该是Node类中的复制构造函数:

    Node::Node(const Node &other) : left(0), right(0)
    {
        this->data = other.data; // This must be a deep copy
        if (other.left)
            this->left = new Node(other.left);
        if (other.right)
            this->right = new Node(other.right);
    }
    
  2. 这是由BinTree 赋值运算符调用的:

    BinTree& BinTree::operator=(const BinTree &other)
    {
        delete root;
        this->root = 0;
        if (other.root)
            this->root = new Node(other.root);
        return *this;
    }
    
  3. 您不需要递归销毁方法。 BinTree 析构函数中只需要delete root;Node 的析构函数:

    Node::~Node()
    {
        delete left;
        delete right;
    }
    
  4. data 的复制必须是深拷贝。例如,如果它是 C 字符串,则在 Node 的析构函数中使用 strdup(),free()。如果是类,则该类必须有赋值运算符。

【讨论】:

  • Node 必须是这个练习的结构,我可以从那里做什么??
  • 没有任何区别,它仍然可以有运算符和构造函数和析构函数。奇怪的要求。
猜你喜欢
  • 2013-11-21
  • 2018-09-20
  • 2023-03-07
  • 2014-10-16
  • 2023-03-08
  • 1970-01-01
  • 2021-12-20
  • 2021-06-15
  • 1970-01-01
相关资源
最近更新 更多