C++ 自平衡AVL树内存泄漏

C++ 自平衡AVL树内存泄漏,c++,memory-leaks,avl-tree,C++,Memory Leaks,Avl Tree,所以我一直在研究这个自平衡AVL树,我觉得它工作正常,但是有一些内存泄漏。我已经搜索了一百万次,感觉就像是在试图找出我做错了什么,但我对这整个内存泄漏事件还不熟悉,显然需要了解更多。如果有人能帮我解决问题,或者能看到漏洞在哪里,那就太棒了,下面是我的AVL树的代码: #pragma once #include <algorithm> #include <fstream> #include "LinkedList.h" template <typename Item

所以我一直在研究这个自平衡AVL树,我觉得它工作正常,但是有一些内存泄漏。我已经搜索了一百万次,感觉就像是在试图找出我做错了什么,但我对这整个内存泄漏事件还不熟悉,显然需要了解更多。如果有人能帮我解决问题,或者能看到漏洞在哪里,那就太棒了,下面是我的AVL树的代码:

#pragma once
#include <algorithm>
#include <fstream>
#include "LinkedList.h"

template <typename ItemType>

class AVLTreeSet {

private:

  struct Node {
    ItemType info;
    Node* left;
    Node* right;
    int height;
  };

  Node* root;
  int size;

public:
    AVLTreeSet()
    {
        root = NULL;
        size = 0;
    }

    ~AVLTreeSet()
    {
        clear();
    }
    void clear()
    {
        Node* n = root;
        if(n != NULL)
        {
            clearTree(n->left);  
            clearTree(n->right); 
            delete n;
        }
        root = NULL;
    }
    void clearTree(Node* n)
    {
        if(n != NULL)
        {
            clearTree(n->left);   
            clearTree(n->right);  
            delete n;        
        }

    }

    void print(std::ofstream &out)
    {
        //cout << "HERE" << endl;
        LinkedList<Node*> list;
        int level = 0;
        int levelSize;
        int count = 0;
        Node* n = root;
        if (n == NULL)
        {
            return;
        }
        list.insert(n);
        levelSize = list.getSize();
        while(list.getSize() != 0)
        {
            count = 0;
            out << "level " << level << ": ";
            for (unsigned i = levelSize; i > 0; i--)
            {
                count++;
                if (count > 8)
                {
                    out << std::endl;
                    out << "level " << level << ": ";
                    count = 0;
                }
                n = list.getInfo();
                out <<n->info << "(" << getHeight(n) << ") ";
                if (n->left != NULL)
                {
                    //cout << "left is not null" << endl;
                    list.insert(n->left);
                }
                if (n->right != NULL)
                {
                    list.insert(n->right);
                    //cout << "right is not null" << endl;          
                }
                list.remove();

            }

            levelSize = list.getSize();
            level++;
            out << std::endl;
            //levelSize = list.getSize();
        }
    }
    void insert(const ItemType& item) 
    {
        //cout << "Insert FUNCTION" << endl;
        Node* current = root;

        if (current == NULL)
        { 
            //cout << "ADD FUNCTION NULL" << endl;
            current = new Node;
            current->info = item;
            current->left = NULL;
            current->right = NULL;
            current->height = 0;
            root = current;
            size++;
            //cout << current->info << endl;
            //cout << current->height << endl;
            return;
        }
        if (current->info > item)
        {
            current->left = add(item, current->left);
        }
        if (current->info < item)
        {
            current->right = add(item, current->right);
        }
        current = balance(current);
        root = current;

    }
    Node* add(const ItemType& item, Node* current) 
    {
        if (current == NULL)
        {
            current = new Node;
            current->info = item;
            current->left = NULL;
            current->right = NULL;
            current->height = 0;
            size++;
        }

        if (current->info > item)
        {
            current->left = add(item, current->left);
        }
        if (current->info < item)
        {
            current->right = add(item, current->right);
        }
        return current;
    }
    void remove(const ItemType& item)
    {
        Node* current = root;
        if (current == NULL)
        {
            //cout << "NULL" << endl;
            return;
        }
        if (current->info == item)
        {
            //cout << "FOUND" << endl;
            current = removeNext(item, current);
            current = balance(current);
            root = current;
            return;
        }
        if (current->info > item)
        {
            //cout << "LEFT" << endl;
            current->left = removeNext(item, current->left);
            if (current == root)
            {
                root = balance(current);
            }
            return;
        }
        if (current->info < item)
        {
            //cout << "RIGHT" << endl;
            current->right = removeNext(item, current->right);
            if (current == root)
            {
                root = balance(current);
            }
            return;
        }
    }
    Node* removeNext(const ItemType& item, Node* current)
    {
        Node* temp;
        if (current != NULL)
        {
        if (current->info > item)
        {
            //cout << "REMOVENEXT LEFT" << endl;
            current->left = removeNext(item, current->left);
            return current;
        }
        if (current->info < item)
        {
            //cout << "REMOVENEXT RIGHT" << endl;
            current->right = removeNext(item, current->right);
            return current;
        }
            //cout << "FOUND" << endl;
            if (current->left != NULL && current->right != NULL)
            {
                //cout << "LEFT AND RIGHT CHILDREN" << endl;
                temp = current;
                current = CTR(current->right);
                current->left = temp->left;
                //cout << current->info << endl;
                //looker = removeNext(current->info, temp->right);
                delete temp;
                size--;
                current = balance(current);
                return current;
            }
            else if (current->right != NULL)
            {
                //cout << "RIGHT ONE CHILD" << endl;
                temp = current;
                current = current->right;
                delete temp;
                size--;
                current = balance(current);
                return current;
            }
            else if (current->left != NULL)
            {
                //cout << "LEFT ONE CHILD" << endl;
                temp = current;
                current = current->left;
                delete temp;
                size--;
                current = balance(current);
                return current;
            }
            //cout << "CURRENT NODE" << endl;
            delete current;
            size--;
            return NULL;
        }
        //cout << "NOT FOUND" << endl;
        return current;
    }
    Node* CTR(Node* current)
    {
        while(current->left != NULL)
        {
            //cout << "ENTERED LOOP" << endl;
            current = current->left;
        }
        //cout << current->info << endl;
        return current;

    }
    bool find(const ItemType& item) 
    {
        Node* current = root;
        bool find = false;
        if (current == NULL)
        {
            return find;
        }
        if (item == current->info)
        {
            find = true;
            return find;
        }
        if (current->info > item && current->left != NULL)
        {
            find = findLeft(item, current->left);
        }
        if (current->info < item && current->right != NULL)
        {
            find = findRight(item, current->right);
        }
        return find;
    }
    bool findLeft(const ItemType& item, Node* current)
    {
        bool find = false;
        if (item == current->info)
        {
            find = true;
            return find;
        }
        if (current->info > item && current->left != NULL)
        {
            find = findLeft(item, current->left);
        }
        if (current->info < item && current->right != NULL)
        {
            find = findRight(item, current->right);
        }
        return find;
    }
    bool findRight(const ItemType& item, Node* current)
    {
        bool find = false;
        if (item == current->info)
        {
            find = true;
            return find;
        }
        if (current->info > item && current->left != NULL)
        {
            find = findLeft(item, current->left);
        }
        if (current->info < item && current->right != NULL)
        {
            find = findRight(item, current->right);
        }
        return find;
    }
    int getHeight(Node* temp)
    {
        int h = 0;
        if (temp != NULL)
        {
            int l_height = getHeight(temp->left);
            int r_height = getHeight(temp->right);
            int max_height = std::max(l_height, r_height);
            h = max_height + 1;
        }
        return h;
    }
    void setHeight(Node* n)
    {
        n->height = std::max(getHeight(n->right), getHeight(n->left)) + 1;
    }

    Node* balance(Node* n)
    {
        if (size == 1)
        {
            return n;
        }
        else if(getHeight(n->left) - getHeight(n->right) > 1) //n is out of balance 
        {   
            //cout << "BALANCE RIGHT" << endl;
            n = balanceToRight(n);
        }
        else if(getHeight(n->right) - getHeight(n->left) > 1)
        {
            //cout << "BALANCE LEFT" << endl;
            n = balanceToLeft(n);
        }   
            return n;
    }
    Node* balanceToRight(Node* n)
    {
        if(getHeight(n->left->right) > getHeight(n->left->left))
            {
                n->left = rotateLeft(n->left); //<--- extra step for double rotate
            }
            n = rotateRight(n); //<--- this is for single
        return n;
    }
    Node* balanceToLeft(Node* n)
    {
        if(getHeight(n->right->left) > getHeight(n->right->right))
            {
                n->right = rotateRight(n->right); //<--- extra step for double rotate
            }
            n = rotateLeft(n); //<--- this is for single
        return n;
    }
    Node* rotateRight(Node* n)
    {
        Node* temp = n->left;
        n->left = temp->right;
        temp->right = n;
        setHeight(n); //<--- set first
        setHeight(temp);
        return temp;
    }
    Node* rotateLeft(Node* n)
    {
        Node* temp = n->right;
        n->right = temp->left;
        temp->left = n;
        setHeight(n); //<--- set first
        setHeight(temp);
        return temp;
    }

};
#pragma一次
#包括
#包括
#包括“LinkedList.h”
样板
类AVLTreeSet{
私人:
结构节点{
项目类型信息;
节点*左;
节点*右;
内部高度;
};
节点*根;
整数大小;
公众:
AVLTreeSet()
{
root=NULL;
尺寸=0;
}
~AVLTreeSet()
{
清除();
}
无效清除()
{
节点*n=根;
如果(n!=NULL)
{
clearTree(n->左);
clearTree(n->右侧);
删除n;
}
root=NULL;
}
void clearTree(节点*n)
{
如果(n!=NULL)
{
clearTree(n->左);
clearTree(n->右侧);
删除n;
}
}
无效打印(标准::流和输出)
{
//cout left=添加(项目,当前->左侧);
}
如果(当前->信息<项目)
{
当前->右侧=添加(项目,当前->右侧);
}
回流;
}
作废删除(const ItemType&item)
{
节点*当前=根;
如果(当前==NULL)
{
//cout info<项目)
{
//不正确);
如果(当前==根)
{
根=平衡(当前);
}
回来
}
}
节点*removeNext(常量项类型&项,节点*current)
{
节点*温度;
如果(当前!=NULL)
{
如果(当前->信息>项目)
{
//不能离开);
回流;
}
如果(当前->信息<项目)
{
//不正确);
回流;
}
//不正确!=空)
{
//cout left=temp->left;
//cout info,temp->right);
删除临时文件;
大小--;
电流=平衡(电流);
回流;
}
else if(当前->右侧!=NULL)
{
//不能左!=空)
{
//cout inforight!=NULL)
{
find=findRight(项目,当前->右侧);
}
返回查找;
}
bool findLeft(常量项类型&项,节点*当前)
{
bool find=false;
如果(项目==当前->信息)
{
发现=真;
返回查找;
}
如果(当前->信息>项目和当前->左侧!=NULL)
{
find=findLeft(项目,当前->左侧);
}
如果(当前->信息right!=NULL)
{
find=findRight(项目,当前->右侧);
}
返回查找;
}
布尔findRight(常量项类型和项,节点*当前)
{
bool find=false;
如果(项目==当前->信息)
{
发现=真;
返回查找;
}
如果(当前->信息>项目和当前->左侧!=NULL)
{
find=findLeft(项目,当前->左侧);
}
如果(当前->信息right!=NULL)
{
find=findRight(项目,当前->右侧);
}
返回查找;
}
int getHeight(节点*temp)
{
int h=0;
如果(温度!=NULL)
{
int l_height=getHeight(临时->左);
int r_height=getHeight(温度->右侧);
int max_height=std::max(l_height,r_height);
h=最大高度+1;
}
返回h;
}
无效设置高度(节点*n)
{
n->height=std::max(getHeight(n->right),getHeight(n->left))+1;
}
节点*余额(节点*n)
{
如果(大小==1)
{
返回n;
}
否则如果(getHeight(n->left)-getHeight(n->right)>1)//n不平衡
{   
//不能左)大于1)
{
//cout right)>getHeight(n->left->left))
{
n->left=rotateLeft(n->left);//left)>getHeight(n->right->right))
{
n->右=旋转右(n->右);//左=临时->右;
温度->右=n;
setHeight(n);//右;
n->右=温度->左;
温度->左=n;

setHeight(n);//您如何知道存在内存泄漏

除非您使用某种工具查找内存泄漏,例如@jsantander建议的valgrind,否则请尝试以下操作:

  • 避免代码重复。当前表单中有太多的重复。例如,
    clear()
    可以通过调用
    cleartree(root)
    来简化。类似于
    insert()

  • 打印/记录每个内存分配(
    new
    )和释放(
    delete
    )的内存

  • 始终增加计数器,
    newCount
    deleteCount
    。在有效方法的末尾,添加一个断言,
    assert(newCount-deleteCount==size);
    。在第一次出现内存泄漏时,
    assert()
    将爆炸。请参阅第7页“其他经验”


  • 你试过运行它吗?你有漏洞,因为你正在手动调用
    new
    delete
    。停止。你是一个简单的定向树。用
    std::unique\u ptr
    替换子
    节点*
    ,在需要时实现
    移动
    ,那么我敢说你有漏洞。你可能必须编写
    模板td::unique\u ptr make_unique(Args&&…Args)
    从客户机代码中删除
    新的
    ,但这可能是过分的:在您的情况下,您不需要