For my current programming assignment I have to construct a binary search tree and use it to insert words from a file in alphabetical order, to make a concordance list. The program is complete and outputs correctly; the main bulk of the program works perfectly. But when the program finishes and destructors are called, it crashes with error in ./concordancebst : free(): invalid pointer
. I'm at a loss as to what the problem is, my destructor looks like it would work and looking at code online it seems as though it should work as well. I could probably get around this by using a std::unique_ptr
but it seems a bit overkill in the sense of the scope of the program (also overkill in the sense that we haven't covered smart pointers, everything we have done in the class involving dynamic memory has been handled through manual allocating/deallocating).
BST.h
#ifndef BST_H
#define BST_H
#include <string>
class BST {
public:
BST() { root = nullptr; }
~BST();
void insert(const std::string word);
int getCount(const std::string word);
int length();
friend std::ostream& operator << (std::ostream &out_s, BST b);
private:
struct Node {
std::string word;
int count;
Node *left;
Node *right;
Node() { word = ""; count = 0; left = nullptr; right = nullptr;}
~Node();
};
Node *root;
void RInsert(Node* &t, std::string word);
int countNodes(Node *p);
void print(Node *p, std::ostream &out_s);
};
#endif
BST.cpp
#include "BST.h"
#include <string>
#include <iostream>
#include <iomanip>
BST::Node::~Node() {
delete left;
delete right;
}
BST::~BST() {
delete root;
}
int BST::countNodes(Node *p) {
if(p == nullptr)
return 0;
else
return countNodes(p->left) + countNodes(p->right) + 1;
}
int BST::getCount(const std::string word) {
Node *p = root;
while(true) {
if(p == nullptr)
return 0;
else if(word.compare(p->word) < 0)
p = p->left;
else if(word.compare(p->word) == 0)
return p->count;
else
p = p->right;
}
}
int BST::length() {
return countNodes(root);
}
void BST::RInsert(Node* &t, std::string word) {
if(t == nullptr) {
t = new Node;
t->word = word;
t->left = nullptr;
t->right = nullptr;
t->count++;
}
else if(word.compare(t->word) == 0)
t->count++;
else if(word.compare(t->word) < 0)
RInsert(t->left, word);
else //word.compare(t->word > 0)
RInsert(t->right, word);
}
void BST::insert(const std::string word) {
RInsert(root, word);
}
void BST::print(Node *p, std::ostream &out_s) {
if(p != nullptr) {
print(p->left, out_s);
out_s << std::setw(13) << p->word << std::setw(10) << p->count << std::endl;
print(p->right, out_s);
}
}
std::ostream &operator << (std::ostream &out_s, BST b) {
out_s << std::setw(13) << "Word" << std::setw(10) << "Count" << std::endl;
out_s << "---------------------------------------------" << std::endl;
b.print(b.root, out_s);
out_s << "---------------------------------------------" << std::endl;
out_s << "The file contains " << b.length() << " distinct words." << std::endl;
return out_s;
}