对于这个程序,我正在为单词字典创建一个AVL自平衡二进制搜索树,这将使用户能够根据排名查找单词,rank是在当前查找的节点数节点+ 1,或者他们可以选择在树中给出一个随机字。不幸的是,当我运行此代码时:
#include "DictionaryAVT.h"
#include<string>
#include<iostream>
#include<sstream>
#include<algorithm>
#include<fstream>
#include<time.h>
#include<stdlib.h>
using namespace std;
Node:: Node()
{
left = right = NULL;
}
Node::~Node()
{
delete this->left;
delete this->right;
this->left = this->right = NULL;
height = 1;
}
Node:: Node(string str)
{
word = str;
height = 1;
left = NULL;
right = NULL;
}
void Node::toString()
{
cout << "Word: " << word;
}
BST::BST()
{
this->root = NULL;
createDictionary();
}
string BST:: removePunctuation(string * str)
{
{
string temp = *str;
for(int i = 0; i < temp.size(); i++)
{
if(ispunct(temp[i]))
temp.erase(i--, 1);
}
return temp;
}
}
void BST:: clear(Node * n)
{
if(n->left != NULL)
clear(n->left);
if(n->right != NULL)
clear(n->right);
delete n;
n = NULL;
size--;
}
void BST:: toString(Node * r)
{
if(r)
{
r->toString();
toString(r->left);
toString(r->right);
}
}
void BST:: toString()
{
if(root)
{
root->toString();
toString(root->left);
toString(root->right);
}
}
int BST:: height(Node * n)
{
if(n)
{
return 1+(height(n->left) + height(n->right));
}
else
return 0;
}
void BST::LR(Node*& k2)
{
Node* k1 = k2->left;
k2->left = k1->right;
k1 -> right = k2;
k2->height = (height(k2->left)+(height(k2->right)))+1;
k1->height = (height(k1->left) + (height(k1->right)))+1;
k2 = k1;
}
void BST::RR(Node*& k2)
{
Node* k1 = k2 -> right;
k2 -> right = k1 -> left;
k1 -> left = k2;
k1->height = (height(k1->left)+(height(k1->right)))+1;
k2->height = (height(k2->right)+(height(k2->left)))+1;
k2 = k1;
}
void BST::insert(string word, Node *& root)
{
if(!root)
{
root = new Node(word);
}
else if(word < root->word)
{
insert(word, root->left);
if(height(root->left)-height(root->right)>1)
{
if(height(root->left->left) >= height(root->left->right))
{
LR(root);
}
else
{
RR(root->left);
LR(root);
}
}
}
else if(root->word < word)
{
insert(word, root->right);
if(height(root->right) - height(root->left) > 1)
{
if(height(root->right->right)>=height(root->right->left))
{
RR(root);
}
else
{
LR(root->right);
RR(root);
}
}
}
root->height = 1 + (height(root->left)+height(root->right));
}
string BST:: search(Node * root, int x)
{
if(!root)
{
return "No Node found";
}
else if(x < root->height)
search(root->left, x);
else if(x > root->height)
search(root->right,x);
else
return root->word;
}
void BST:: addWord(string str)
{
insert(str, root);
}
string BST:: getWordOfDay(int x)
{
int m = 1+height(root->left);
if(m == x)
return root->word;
else if(m > x)
return search(root->left, x);
else
return search(root->right,(x-m));
}
void BST:: createDictionary()
{
string str;
ifstream inFile("english.txt");
if(inFile.is_open())
{
getline(inFile, str);
while(inFile.eof() != true)
{
addWord(removePunctuation(&str));
getline(inFile, str);
}
}
}
void BST:: driver()
{
string in;
cout << "Please input R for a word with said rank, or W if you would like the word of the day" << endl;
cin >> in;
while(in == "R" || in == "W")
{
BST *bst = new BST();
if(in == "R" || in == "r")
{
int x;
cout << "Please input a rank: ";
cin >> x;
cout << x << endl;
cout << "Word at rank " << x << "is: " << bst->getWordOfDay(x) << endl;
}
else if(in == "W" || in == "w")
{
srand(time(NULL));
int x = rand() % bst->numberOfWords() + 1;
cout << "Word of the day is: " << bst->getWordOfDay(x) << endl;
}
cout << "Please input R for a word with said rank, or W if you would like the word of the day" << endl;
cin >> in;
}
}
int main()//tester method
{
BST* bst = new BST();
cout << bst->numberOfWords() << endl;
cout << bst->getWordOfDay(1) << endl;
}
编译后我得到这个错误:
*** glibc detected *** ./DictionaryAVT: free(): invalid pointer: 0x402e1394 ***
======= Backtrace: =========
/lib/libc.so.6(+0x6d6f4)[0x401e86f4]
/lib/libc.so.6(+0x6f003)[0x401ea003]
/lib/libc.so.6(cfree+0x6d)[0x401ed13d]
/usr/lib/libstdc++.so.6(_ZdlPv+0x1f)[0x400a061f]
/usr/lib/libstdc++.so.6(_ZNSs4_Rep10_M_destroyERKSaIcE+0x1b)[0x4010b11b]
/usr/lib/libstdc++.so.6(+0xb8160)[0x4010b160]
/usr/lib/libstdc++.so.6(_ZNSsD1Ev+0x2e)[0x4010b1ce]
./DictionaryAVT[0x8049921]
./DictionaryAVT[0x8049912]
./DictionaryAVT[0x8049912]
./DictionaryAVT[0x8049912]
./DictionaryAVT[0x8049912]
./DictionaryAVT[0x8049912]
./DictionaryAVT[0x8049912]
./DictionaryAVT[0x8049912]
./DictionaryAVT[0x8049912]
./DictionaryAVT[0x8049912]
./DictionaryAVT[0x8049912]
./DictionaryAVT[0x8049912]
./DictionaryAVT[0x8049912]
./DictionaryAVT[0x8049912]
./DictionaryAVT[0x8049912]
./DictionaryAVT[0x8049912]
./DictionaryAVT[0x8049912]
./DictionaryAVT[0x8049912]
./DictionaryAVT[0x8049912]
./DictionaryAVT[0x8049912]
./DictionaryAVT[0x8049912]
./DictionaryAVT[0x8049912]
./DictionaryAVT[0x8049912]
./DictionaryAVT[0x8049912]
./DictionaryAVT[0x8049a59]
./DictionaryAVT[0x8049f84]
/lib/libc.so.6(__libc_start_main+0xe5)[0x40191c25]
./DictionaryAVT[0x8048f51]
======= Memory map: ========
08048000-0804b000 r-xp 00000000 00:13 8806711 /home/spsteph/C++/IT 279/Assignment 4/DictionaryAVT
0804b000-0804c000 r--p 00002000 00:13 8806711 /home/spsteph/C++/IT 279/Assignment 4/DictionaryAVT
0804c000-0804d000 rw-p 00003000 00:13 8806711 /home/spsteph/C++/IT 279/Assignment 4/DictionaryAVT
0804d000-0829f000 rw-p 00000000 00:00 0 [heap]
40000000-4001f000 r-xp 00000000 08:02 145836 /lib/ld-2.11.3.so
4001f000-40020000 r--p 0001e000 08:02 145836 /lib/ld-2.11.3.so
40020000-40021000 rw-p 0001f000 08:02 145836 /lib/ld-2.11.3.so
40021000-40023000 rw-p 00000000 00:00 0
40053000-40138000 r-xp 00000000 08:02 377022 /usr/lib/libstdc++.so.6.0.17
40138000-4013c000 r--p 000e5000 08:02 377022 /usr/lib/libstdc++.so.6.0.17
4013c000-4013d000 rw-p 000e9000 08:02 377022 /usr/lib/libstdc++.so.6.0.17
4013d000-40144000 rw-p 00000000 00:00 0
40144000-4016a000 r-xp 00000000 08:02 145851 /lib/libm-2.11.3.so
4016a000-4016b000 r--p 00026000 08:02 145851 /lib/libm-2.11.3.so
4016b000-4016c000 rw-p 00027000 08:02 145851 /lib/libm-2.11.3.so
4016c000-40179000 r-xp 00000000 08:02 145962 /lib/libgcc_s.so.1
40179000-4017a000 r--p 0000c000 08:02 145962 /lib/libgcc_s.so.1
4017a000-4017b000 rw-p 0000d000 08:02 145962 /lib/libgcc_s.so.1
4017b000-402de000 r-xp 00000000 08:02 145843 /lib/libc-2.11.3.so
402de000-402e0000 r--p 00162000 08:02 145843 /lib/libc-2.11.3.so
402e0000-402e1000 rw-p 00164000 08:02 145843 /lib/libc-2.11.3.so
402e1000-402e7000 rw-p 00000000 00:00 0
40300000-40321000 rw-p 00000000 00:00 0
40321000-40400000 ---p 00000000 00:00 0
bf88e000-bf8af000 rw-p 00000000 00:00 0 [stack]
ffffe000-fffff000 r-xp 00000000 00:00 0 [vdso]
make: *** [run] Aborted
有人能看出为什么会这样吗?
答案 0 :(得分:0)
您的错误是指“无效指针”,我在您的代码中看到可能发生此错误的两个潜在问题。
<强> 1。析构函数:
Node::~Node()
{
delete this->left;
delete this->right;
this->left = this->right = NULL;
height = 1;
}
如果您没有初始化left
和right
,则两个变量都为NULL
,这将导致删除无效指针。我会改为:
Node::~Node()
{
if (this->left!=NULL)
delete this->left;
if (this->left!=NULL)
delete this->right;
}
请注意,我没有设置变量(如height=1
),因为删除对象时会调用此函数。
<强> 2。功能明确:
void BST:: clear(Node * n)
{
if(n->left != NULL)
clear(n->left);
if(n->right != NULL)
clear(n->right);
delete n;
n = NULL;
size--;
}
虽然您确实检查了n->left != NULL
,但是不检查n
是否为NULL。您可以将其更改为:
void BST:: clear(Node * n)
{
if (n != NULL) {
if(n->left != NULL)
clear(n->left);
if(n->right != NULL)
clear(n->right);
delete n;
size--;
}
}
当您使用new
创建对象时,请务必将其删除,并在使用delete
时确保您传递的指针有效!
编辑像Alex M.评论的那样,delete NULL
does nothing在第一点上进行更改是不必要的。第二次n!=NULL
检查仍然是必要的,因为您访问了它的变量left
和right
。