Please help the code compiles but then gives runtime error and I have no Idea why please help with the insert of the book

the .h file

#ifndef BOOK_H
#define BOOK_H

#include <string>

#include "Person.h"

using namespace std;
struct node
{
    node *left;
    node *right;
    Person data;
};

class Book
{
    public:
        Book();
        virtual ~Book();

        void insert(Person contact);
        node *search(string name);
        void removeContact(string name);
    protected:
    private:
        node *root;
        node *current;
};

#endif // BOOK_H

the actual code

#include <string>

#include "Book.h"

using namespace std;
Book::Book()
{
    root = NULL;
}

Book::~Book()
{

}

void Book::insert(Person contact)
{
    string name = contact.getName();
    int number = contact.getNumber();
    if(root == NULL)
    {
        root->data = Person(name, number);
        cout << "\nroot\n";
        root->left = NULL;
        root->right = NULL;
        current = root;
    }
    else if(contact.getName() < current->data.getName())
    {
        if(current->left == NULL)
        {
            current->left->data = contact;
            current = root;
            cout << "\nleft\n";
        }
        else
        {
            current = current->left;
            insert(contact);
        }
    }
    else if(contact.getName() >= current->data.getName())
    {
        if(current->right == NULL)
        {
            current->right->data = contact;
            current = root;
        }
        else
        {
            current = current->right;
            insert(contact);
        }
    }

}

I am not surprised this doesn't run! You have a head node called root. However,
rather than add a new copy of the memory for it, you do this:

if(root == NULL)
  {
    // THIS IS A RUNTIME ERROR:
    root->data = Person(name, number);
    root->left = NULL;
    root->right = NULL;
    current = root;
  }

Note that root is 0. BUT then you access the object pointed to by it. That isn't going to work.

What you need to do is this:

if (root == NULL )
  {
     root=new node;
     // ... etc.

However, when you do that, you have to (a) ensure that you are deleting the tree in the destructor of Book. (b) ensure that a sensible copy constructor and assignment operator are written for book. (c) ensure that Person has appropriate copy constructor and assignment operator, be careful about setting current.

Finally, you are obviously moving around non-trivial objects, e.g. Person etc. Please use references, e.g.
I think Book should look like this:

class Book
{
  public:
    Book();
    Book(const Book&);  // Non simple data object ALWAYS provide a copy constructor
    Book& operator=(const Book&);   
    virtual ~Book();

    void insert(const Person&);     // Note the change to a reference
    node* search(const std::string&);
    void removeContact(const std::string&);
private:
   node* root;
   node* current;
};

Also if Book is has a virtual destructor, so will be inherited from, does insert/search etc need to be virtual too?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.