I have code below that consist of binary tree data structure:
#include <bits/stdc++.h>
#define DEFAULT_NODE_VALUE 0
using namespace std;
template <class T>
class node{
public:
T val;
node* right = 0;
node* left = 0;
node(T a):val(a){}
};
template <class T>
class tree{
public:
node<T>* root = new node<T>(DEFAULT_NODE_VALUE);
tree(T inp_val){
root->val = inp_val;
}
void inorder_traverse(node<T>* temp){
if (!temp)
return;
inorder_traverse(temp->left);
cout << temp->val << " -> ";
inorder_traverse(temp->right);
}
void inorder_traverse(){
inorder_traverse(root);
}
};
int main()
{
tree<string> my_tree("mantap");
my_tree.root->right = new node<string>("ok");
my_tree.root->left = new node<string>("haha");
my_tree.inorder_traverse();
return 0;
}
When I run it, it showed me an exeption like this below:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_M_construct null not valid
Can anyone help me to fix this runtime error, please? Thanks in advance...
You're trying to initialize an std::string
with 0
. std::string
doesn't have a ctor that takes just an int
, but it does have one that takes a pointer, and an integer literal 0
can convert implicitly to a pointer--specifically, a null pointer.
But, when you pass a pointer to initialize an std::string
, it's required to be a non-null pointer, so passing zero breaks things (and the error message you're getting is telling you that you've tried to break it).
My advice would be to get rid of your: DEFAULT_NODE_VALUE
, and instead provide a default argument to value initialize the item in the node:
node(T a = T()):val(a){}
In which case, it'll work about as it previously did for things like node<int>
, but will also work correctly for types that can't be initialized from 0
. This also gets rid of the ugly DEFAULT_NODE_VALUE
in the client code.