So I'm implementing a templated binary tree dictionary as a class that inherits from an abstract Dictionary class, and I have a problem with my add function that I can't figure out.
Basically, my tree has nodes that have both a key and value, and pointers to its parent, left child, and right child. The code for the node is
struct bNode {
K key;
V value;
bNode* left;
bNode* right;
bNode* parent;
};
(I know using shared_ptr is better than raw pointers but it wasn't required for this project)
The tree also has a member pointer bNode* root
.
To test my tree, I add elements to it and call display after each one. So far, displaying an empty list works properly, as does displaying a list with one element and with two elements. When I add a third, though, and call display, it breaks...
Here's the code for the add function
void add(K key, V value) override {
// if list is empty, create new root node
if (!root){
root = new bNode;
root->key = key;
root->value = value;
return;
}
bNode* node = root;
// travel down tree, checking each node on the way
while (true){
// if node exists with passed-in key, change value to passed-in value
if (node->key == key){
node->value = value;
return;
}
// if key < or > node and node has a left / right child, travel left / right branch
// if node doesn't have a left / right child, create one and pass in key
if (key < node->key){
if (node->left){
node = node->left;
} else {
node->left = new bNode;
node->left->parent = node;
node->left->key = key;
node->left->value = value;
return;
}
} else {
if (node->right){
node = node->right;
} else {
node->right = new bNode;
node->right->parent = node;
node->right->key = key;
node->right->value = value;
return;
}
}
}
}
here's display
void display() const override {
if (!root){
return;
}
displayHelper(root);
cout << endl;
}
and here's displayHelper
void displayHelper(bNode* node) const {
cout << "(" << node->key << ", " << node->value << ") ";
if (node->left){
cout << "displaying left... <" << node->key << "> ";
displayHelper(node->left);
}
if (node->right){
cout << "displaying right... <" << node->key << "> ";
displayHelper(node->right);
}
}
The lines that cout "displaying right" and "displaying left" were my attempts to bugfix, as it shouldn't run unless the function is about to display another node. This all worked as expected after displaying the first 2 nodes; however, at the third node, it would display that element, and then print "displaying left <*3rd node's key>...", then crash and give me a segmentation fault.
As far as I can tell, this means that for some reason the code is running as if the third added node, which should be a leaf node, actually has children, but then crashing when it tries to read the member variables for nonexistant nodes.
I can't figure out what's causing the bug, as this is all pretty simple code! Any help would be greatly appreciated!
EDIT: here's an example snippet of code demonstrating the problem;
BSTDictionary<string, int> t;
t.display();
t.add("e", 5);
t.display();
t.add("b", 20);
t.display();
t.add("c", 12);
t.display();
return 0;
when run, the output looks like
(e,5)
(e,5) displaying left... (e) (b,20)
(e,5) displaying left... (e) (b,20) displaying right... (b) (c,12) displaying left... (c)
Process returned -1073741819 (0xC0000005) execution time : 1.993 s
There should be no left child of the node containing (c,12), yet the compiler is trying to run as if there is.