我的红黑树析构器怎么了
What wrong with my Red Black Tree destructor?
我正在构建一个红黑树,但可能有一些问题与我的类RBTree的析构函数。我给树加了10^7的值,然后调用析构函数,但是内存似乎没有被释放。(我看了看系统监视器,我的程序仍然使用200MB)。
你能告诉我析构函数出了什么问题吗?这是我的源代码。
对不起,我的英语很差。
#include<cstdio>
#include<cstdlib>
#include<iostream>
using namespace std;
enum Color {RED, BLACK};
template<class Data> class RBNode;
template<class Data> class RBTree;
template<class Data> class RBNode {
Color color; RBNode *p, *left, *right;
public:
Data v;
RBNode(Color color, RBNode *p, RBNode *left, RBNode *right, Data v):
color(color), p(p), left(left), right(right), v(v) {}
RBNode() {}
friend class RBTree<Data>;
};
template<class Data> class RBTree {
typedef RBNode<Data> Node;
typedef Node * PNode;
PNode root, nil;
void LeftRotate(PNode x) {
PNode y = x->right; x->right = y->left;
if(y->left != nil) y->left->p = x;
y->p = x->p;
if(x->p == nil) root = y;
else if(x == x->p->left) x->p->left = y;
else x->p->right = y;
y->left = x; x->p = y;
}
void RightRotate(PNode y) {
PNode x = y->left; y->left = x->right;
if(x->right != nil) x->right->p = y;
x->p = y->p;
if(y->p == nil) root = x;
else if(y == y->p->left) y->p->left = x;
else y->p->right = x;
x->right = y; y->p = x;
}
void insertFixUp(PNode z) {
while(z->p->color == RED) {
if(z->p == z->p->p->left) {
PNode y = z->p->p->right;
if(y->color == RED) z->p->color = y->color = BLACK, z->p->p->color = RED, z = z->p->p;
else {
if(z == z->p->right) LeftRotate(z = z->p);
z->p->color = BLACK; z->p->p->color = RED; RightRotate(z->p->p);
}
} else {
PNode y = z->p->p->left;
if(y->color == RED) z->p->color = y->color = BLACK, z->p->p->color = RED, z = z->p->p;
else {
if(z == z->p->left) RightRotate(z = z->p);
z->p->color = BLACK; z->p->p->color = RED; LeftRotate(z->p->p);
}
}
}
root->color = BLACK;
}
public:
RBTree() {
nil = new Node;
nil->color = BLACK;
nil->p = nil->left = nil->right = nil;
nil->v = Data();
root = nil;
}
~RBTree() {
delete root;
delete nil;
}
void insert(Data v) {
PNode y = nil, x = root;
while(x != nil) {
y = x;
x = v < x->v ? x->left : x->right;
}
PNode z = new Node; *z = Node(RED, y, nil, nil, v);
if(y == nil) root = z;
else if(v < y->v) y->left = z;
else y->right = z;
insertFixUp(z);
}
};
int main() {
RBTree<int> tree;
for(int i = 0; i < 10000000; ++i) tree.insert(i);
tree.~RBTree();
getchar();
return 0;
}
你需要添加一个析构函数到你的RBNode
,它删除它的子元素:
template<class Data> class RBNode {
...
~RBNode() {
delete left;
delete right;
}
...
};
实际上,当树被删除时,您将删除根节点,但是根节点本身不会释放其资源。因此,您将丢失对根的子节点及其所有子节点的所有引用,等等。因为你不再有对这些节点的引用,你不能删除它们,你有内存泄漏。
析构函数确保当我们即将丢失对节点的子节点的引用时,这些子节点(以及它们的子节点等等)将被释放。
首先,问题在于您没有使用智能指针。其次,您没有在Node类中使用智能指针,因此当根被删除时,其他对象都不会被删除。
树节点似乎不会递归地删除它们的子节点。您需要在节点中使用析构函数,然后当根节点被销毁时,所有内容都将级联。
析构函数只释放两个元素:root和nil。要释放树的其余部分,您应该以某种方式向下传播释放元素,如:
~RBNode() {
if (left != nil ) delete left;
if (right != nil) delete right;
}
我找到了我的析构函数,但我有一些更多的属性,如大小和父指针,但我认为这将有助于
~RBTree() {
RBNode *p(root);
while(size!=0) {
if(p==root && size==1) { delete root; size--;}
else if(p->right!=0) p=p->right;
else if(p->left!=0) p=p->left;
else {
RBNode *c(p);
p=p->parent;
if(p->left==c) {
delete c;
p->left=0;
}
else {
delete c;
p->right=0;
}
size--;
}
}
}
相关文章:
- 为什么即使调用了析构函数,C++11 中的分离线程也可以执行
- 应该是虚拟析构函数吗?但是怎么做呢?
- 当声明了虚拟析构函数但没有实现时会发生什么情况
- C++析构函数调用了错误的对象
- 尽管使用了 boost::scoped_ptr,我们是否应该删除析构函数中成员的指针
- 有人可以解释一下这里发生了什么(类和构造函数/析构函数)吗?
- 析构函数"Missing vtable",但定义了析构函数
- 添加析构函数后,在程序调用它之前,我就出现了错误
- 我是否正确构建了这些引用和指针函数?如果是,我该如何显式调用我的析构函数
- boost::shared_ptr的析构函数阻止了唯一的线程
- 如果在派生类中定义了虚拟析构函数,但不是层次结构的顶部,该怎么办?C++
- C++ 析构函数调用得太早了
- C++:调用了错误的析构函数
- 声明析构函数虚拟就足够了吗?
- 在作用域结束之前调用了析构函数
- 为什么不为定义了析构函数的类合成move操作呢?
- 如何检查线程中是否调用了析构函数
- 我的红黑树析构器怎么了
- 当派生函数定义了析构函数时,使用复制函数而不是移动函数
- 尽管调用了析构函数,但仍存在内存泄漏