所以我一直在研究這種自平衡AVL樹,我覺得它的工作正常,但有一些內存泄漏。我搜索並經歷了一百萬次,這感覺就像試圖弄清楚我做錯了什麼,但是我對這個內存泄漏事情很陌生,顯然需要了解更多。如果有人能幫助我或者能看到該泄漏可能是將是真棒,這裏是我的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;
}
};
我在與我的main.cpp文件讀取運行程序調用我的AVLtree的命令。我知道它有很多代碼,但我強調,因爲我無法找到它可能發生的地方。謝謝。
您是否嘗試過通過運行它[的valgrind-MEMCHECK(http://valgrind.org/info/tools.html#memcheck)? – jsantander
因爲您正在手動調用'new'和'delete',所以您有泄漏。不要那麼做。你是一棵簡單的定向樹。將'Node *'替換爲'std :: unique_ptr',在需要時執行'move',然後我敢於泄漏。你可能需要編寫'templare std :: unique_ptr make_unique(Args && ... args)'從客戶端代碼中刪除'new',但這可能會過度:在你的的情況下,你不需要處理任意ctors。 –
Yakk
是否存在導致您檢測泄漏的特定命令序列? – jsantander