c++ - BST 的析构函数

标签 c++ memory destructor

我必须实现自己的二叉搜索树。据我所知一切正常,除了析构函数。 这是一些代码(所有析构函数和构造函数)

Node(){
        val = T();
        parent=nullptr;
        lChild = nullptr;
        rChild = nullptr;
    }
    Node(T &valx){
        val=valx;
        parent=nullptr;
        lChild = nullptr;
        rChild = nullptr;
    }
    Node(const Node &other){
        val = other.val;
        if(other.lChild!=nullptr){
            lChild = new Node(*other.lChild);
            lChild->parent=this;
        }
        else
            lChild=nullptr;
        if(other.rChild!=nullptr){
            rChild= new Node(*other.rChild);
            rChild->parent=this;
        }
        else
            rChild=nullptr;
    }
    ~Node(){
        if(lChild!=nullptr){
            delete lChild; 
            lChild=nullptr; 
        }
        if(rChild!=nullptr){
            delete rChild; 
            rChild=nullptr; 
        }
    }

Set(){
    root = nullptr;
    sizeOfTree=0;
}
Set(const Set &other){
    if(other.root!=nullptr){
        root = new Node(*other.root);
        root->parent=nullptr;
    }
    else
        root=nullptr;
    sizeOfTree=other.sizeOfTree;
}
~Set()
{
    if(root!=nullptr){
        delete root;
        //root->~Node();
        root=nullptr;
    }
}

通过最简单的测试,valgrind 显示 272 个错误。感谢帮助

@edit:valgrind 输出的一部分:

==6981== Invalid read of size 8
==6981==    at 0x405C29: Set<Pionek>::Node::~Node() (JakbyGomoku4.cpp:53)
==6981==    by 0x4049EA: Set<Pionek>::~Set() (JakbyGomoku4.cpp:152)
==6981==    by 0x404790: Plansza::~Plansza() (in /media/Dokumenty/Workspace/JakbyGomoku4/Debug/JakbyGomoku4)
==6981==    by 0x4015F0: generujPlansze(Plansza&, int, bool, Set<Plansza>&) (JakbyGomoku4.cpp:718)
==6981==    by 0x401746: generujPlansze(Plansza&, int, bool, Set<Plansza>&) (JakbyGomoku4.cpp:745)
==6981==    by 0x4019D5: main (JakbyGomoku4.cpp:792)
==6981==  Address 0x4c34468 is 24 bytes inside a block of size 40 free'd
==6981==    at 0x4A073CC: operator delete(void*) (vg_replace_malloc.c:480)
==6981==    by 0x4049F2: Set<Pionek>::~Set() (JakbyGomoku4.cpp:152)
==6981==    by 0x401E27: Plansza::Plansza(Plansza const&) (JakbyGomoku4.cpp:315)
==6981==    by 0x4015A6: generujPlansze(Plansza&, int, bool, Set<Plansza>&) (JakbyGomoku4.cpp:718)
==6981==    by 0x401746: generujPlansze(Plansza&, int, bool, Set<Plansza>&) (JakbyGomoku4.cpp:745)
==6981==    by 0x4019D5: main (JakbyGomoku4.cpp:792)
==6981== 
==6981== Invalid read of size 8
==6981==    at 0x405C5F: Set<Pionek>::Node::~Node() (JakbyGomoku4.cpp:57)
==6981==    by 0x4049EA: Set<Pionek>::~Set() (JakbyGomoku4.cpp:152)
==6981==    by 0x404790: Plansza::~Plansza() (in /media/Dokumenty/Workspace/JakbyGomoku4/Debug/JakbyGomoku4)
==6981==    by 0x4015F0: generujPlansze(Plansza&, int, bool, Set<Plansza>&) (JakbyGomoku4.cpp:718)
==6981==    by 0x401746: generujPlansze(Plansza&, int, bool, Set<Plansza>&) (JakbyGomoku4.cpp:745)
==6981==    by 0x4019D5: main (JakbyGomoku4.cpp:792)
==6981==  Address 0x4c34470 is 32 bytes inside a block of size 40 free'd
==6981==    at 0x4A073CC: operator delete(void*) (vg_replace_malloc.c:480)
==6981==    by 0x4049F2: Set<Pionek>::~Set() (JakbyGomoku4.cpp:152)
==6981==    by 0x401E27: Plansza::Plansza(Plansza const&) (JakbyGomoku4.cpp:315)
==6981==    by 0x4015A6: generujPlansze(Plansza&, int, bool, Set<Plansza>&) (JakbyGomoku4.cpp:718)
==6981==    by 0x401746: generujPlansze(Plansza&, int, bool, Set<Plansza>&) (JakbyGomoku4.cpp:745)
==6981==    by 0x4019D5: main (JakbyGomoku4.cpp:792)
==6981== 
==6981== Invalid free() / delete / delete[] / realloc()
==6981==    at 0x4A073CC: operator delete(void*) (vg_replace_malloc.c:480)
==6981==    by 0x4049F2: Set<Pionek>::~Set() (JakbyGomoku4.cpp:152)
==6981==    by 0x404790: Plansza::~Plansza() (in /media/Dokumenty/Workspace/JakbyGomoku4/Debug/JakbyGomoku4)
==6981==    by 0x4015F0: generujPlansze(Plansza&, int, bool, Set<Plansza>&) (JakbyGomoku4.cpp:718)
==6981==    by 0x401746: generujPlansze(Plansza&, int, bool, Set<Plansza>&) (JakbyGomoku4.cpp:745)
==6981==    by 0x4019D5: main (JakbyGomoku4.cpp:792)
==6981==  Address 0x4c34450 is 0 bytes inside a block of size 40 free'd
==6981==    at 0x4A073CC: operator delete(void*) (vg_replace_malloc.c:480)
==6981==    by 0x4049F2: Set<Pionek>::~Set() (JakbyGomoku4.cpp:152)
==6981==    by 0x401E27: Plansza::Plansza(Plansza const&) (JakbyGomoku4.cpp:315)
==6981==    by 0x4015A6: generujPlansze(Plansza&, int, bool, Set<Plansza>&) (JakbyGomoku4.cpp:718)
==6981==    by 0x401746: generujPlansze(Plansza&, int, bool, Set<Plansza>&) (JakbyGomoku4.cpp:745)
==6981==    by 0x4019D5: main (JakbyGomoku4.cpp:792)
==6981== 
==6981== Invalid read of size 8
==6981==    at 0x405C6C: Set<Pionek>::Node::~Node() (JakbyGomoku4.cpp:58)
==6981==    by 0x4049EA: Set<Pionek>::~Set() (JakbyGomoku4.cpp:152)
==6981==    by 0x4057AF: Set<Pionek>::clear() (JakbyGomoku4.cpp:222)
==6981==    by 0x40160B: generujPlansze(Plansza&, int, bool, Set<Plansza>&) (JakbyGomoku4.cpp:731)
==6981==    by 0x401746: generujPlansze(Plansza&, int, bool, Set<Plansza>&) (JakbyGomoku4.cpp:745)
==6981==    by 0x4019D5: main (JakbyGomoku4.cpp:792)
==6981==  Address 0x4c334c0 is 32 bytes inside a block of size 40 free'd
==6981==    at 0x4A073CC: operator delete(void*) (vg_replace_malloc.c:480)
==6981==    by 0x4049F2: Set<Pionek>::~Set() (JakbyGomoku4.cpp:152)
==6981==    by 0x401E27: Plansza::Plansza(Plansza const&) (JakbyGomoku4.cpp:315)
==6981==    by 0x4016DE: generujPlansze(Plansza&, int, bool, Set<Plansza>&) (JakbyGomoku4.cpp:742)
==6981==    by 0x4019D5: main (JakbyGomoku4.cpp:792)
==6981== 
==6981== Invalid write of size 8
==6981==    at 0x405C89: Set<Pionek>::Node::~Node() (JakbyGomoku4.cpp:59)
==6981==    by 0x4049EA: Set<Pionek>::~Set() (JakbyGomoku4.cpp:152)
==6981==    by 0x4057AF: Set<Pionek>::clear() (JakbyGomoku4.cpp:222)
==6981==    by 0x40160B: generujPlansze(Plansza&, int, bool, Set<Plansza>&) (JakbyGomoku4.cpp:731)
==6981==    by 0x401746: generujPlansze(Plansza&, int, bool, Set<Plansza>&) (JakbyGomoku4.cpp:745)
==6981==    by 0x4019D5: main (JakbyGomoku4.cpp:792)
==6981==  Address 0x4c334c0 is 32 bytes inside a block of size 40 free'd
==6981==    at 0x4A073CC: operator delete(void*) (vg_replace_malloc.c:480)
==6981==    by 0x4049F2: Set<Pionek>::~Set() (JakbyGomoku4.cpp:152)
==6981==    by 0x401E27: Plansza::Plansza(Plansza const&) (JakbyGomoku4.cpp:315)
==6981==    by 0x4016DE: generujPlansze(Plansza&, int, bool, Set<Plansza>&) (JakbyGomoku4.cpp:742)
==6981==    by 0x4019D5: main (JakbyGomoku4.cpp:792)
==6981== 
==6981== Invalid read of size 8
==6981==    at 0x405C36: Set<Pionek>::Node::~Node() (JakbyGomoku4.cpp:54)
==6981==    by 0x4049EA: Set<Pionek>::~Set() (JakbyGomoku4.cpp:152)
==6981==    by 0x40479C: Plansza::~Plansza() (in /media/Dokumenty/Workspace/JakbyGomoku4/Debug/JakbyGomoku4)
==6981==    by 0x401755: generujPlansze(Plansza&, int, bool, Set<Plansza>&) (JakbyGomoku4.cpp:748)
==6981==    by 0x4019D5: main (JakbyGomoku4.cpp:792)
==6981==  Address 0x4c33448 is 24 bytes inside a block of size 40 free'd
==6981==    at 0x4A073CC: operator delete(void*) (vg_replace_malloc.c:480)
==6981==    by 0x4049F2: Set<Pionek>::~Set() (JakbyGomoku4.cpp:152)
==6981==    by 0x401DF0: Plansza::Plansza(Plansza const&) (JakbyGomoku4.cpp:314)
==6981==    by 0x4016DE: generujPlansze(Plansza&, int, bool, Set<Plansza>&) (JakbyGomoku4.cpp:742)
==6981==    by 0x4019D5: main (JakbyGomoku4.cpp:792)
==6981== 
==6981== Invalid write of size 8
==6981==    at 0x405C53: Set<Pionek>::Node::~Node() (JakbyGomoku4.cpp:55)
==6981==    by 0x4049EA: Set<Pionek>::~Set() (JakbyGomoku4.cpp:152)
==6981==    by 0x40479C: Plansza::~Plansza() (in /media/Dokumenty/Workspace/JakbyGomoku4/Debug/JakbyGomoku4)
==6981==    by 0x401755: generujPlansze(Plansza&, int, bool, Set<Plansza>&) (JakbyGomoku4.cpp:748)
==6981==    by 0x4019D5: main (JakbyGomoku4.cpp:792)
==6981==  Address 0x4c33448 is 24 bytes inside a block of size 40 free'd
==6981==    at 0x4A073CC: operator delete(void*) (vg_replace_malloc.c:480)
==6981==    by 0x4049F2: Set<Pionek>::~Set() (JakbyGomoku4.cpp:152)
==6981==    by 0x401DF0: Plansza::Plansza(Plansza const&) (JakbyGomoku4.cpp:314)
==6981==    by 0x4016DE: generujPlansze(Plansza&, int, bool, Set<Plansza>&) (JakbyGomoku4.cpp:742)
==6981==    by 0x4019D5: main (JakbyGomoku4.cpp:792)

最佳答案

除了复制构造函数和析构函数检查之外,您还缺少 operator= here
也不需要在析构函数中检查 nullptr,it is ok to delelete nullptr .
考虑类似的事情

Node n1;
//set children for n1
{
Node n2;
//set children for n2
n1 = n2;//Now both n1 and n2 points same children, and initial children of n1 becomes mem leak
}//n2 destructor deletes its children leaving n1 pointing to the same already freed memory location

关于c++ - BST 的析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15985987/

相关文章:

c++ - 捕获从用 C++ 编写的 ActiveX 控件抛出的 Javascript 中的异常

c++ - 什么是友元说明符的析构函数?

c++ - g++ __static_initialization_and_destruction_0(int, int) - 它是什么

c++ - 为纯虚析构函数添加定义的目的是什么?

c++ - 是否有私有(private)使用名称=类型;

C++ "Getter"方法在尝试返回同一类中的私有(private)变量时抛出访问冲突

c++ - 使用 strdup() 后将 char* 转换为 int

java - 处理中的内存泄漏

c - 如果线程在释放内存之前被杀死,如何释放线程分配的内存?

amazon-web-services - RDS 吃掉所有交换空间