0

I have been working on this assignment for sometime and cannot figure out what is causing the segmentation fault, any help would be appreciated, here is a copy of my two files!

I am also in the process of fixing my inFile setup, but I would rather focus on that after the fact of the segmentation error.

#include <iostream>
#include <fstream>
#include <string>
#include <list>
#include "source.cpp"

using namespace std;
void scanFile(string fileName);
void printActors(string movie);
void printShows(string actor);

const int MAX_LINE = 128;
int movies = 0;
BST tree;

int main(){
    // Scan file
    scanFile("tvDB.txt");

    // Print all the show titles
    cout << "All show titles:" << endl;
    tree.displayShows();
    cout << endl; // Whitespace


    // Print actors /w given show
    cout << "Actors from 'The Saint'" << endl;
    printActors("The Saint");


    // Print show  /w given actor
    printShows("Tim Conway");


    // Print from decade


    return 0;
}

// Trims the line removing all excess whitespace before and after a sentence
string isolateLine(string line)
{
    int index = 0, start = 0, end = 0;

    //Get the start of the line
    for(int i = 0; i < line.length(); i++)
    {
        if(line[i] != ' ' && line[i] != '\t')
        {
            start = i;
            break;
        }
    }

    // Get the end of the line
    for(int x = line.length(); x >= 0; x--)
    {
        if(line[x] != ' ' && line[x] != '\t')
        {
            end = x;
            break;
        }
    }

    // Trim line
    line = line.substr(start, end);
    return line;
}

// A boolean that returns if the tree is blank, useful for skipping a line and continuing to search for a movie
bool blankLine(string line){
    for(int i = 0; i < line.length(); i++)
    {
        if(line[i] != ' ' && line[i] != '\t')
        {
            return false;
        }
    }
    return true;
}

// Prints all the shows an actor has starred in
void printShows(string actor){
    cout << "Shows with [" << actor << "]:" << endl;
    tree.displayActorsShows(actor);
    cout << endl; // whitespace
}

// Prints all the actors in a particular movie
void printActors(string show)
{
    cout << " Actors for [" << show << "]" << endl;
    tree.displayActors(show);
    cout << endl;
}

// Scans the fild and categorizes every line of data into the proper categories of the show
void scanFile(string fileName)
{
    ifstream inFile;
    inFile.open("tvDB.txt");
    list <string> actors;

    string line = "";
    string title = "";
    string year = "";

    while(getline(inFile, line))
    {
        line = isolateLine(line);

        if(!blankLine(line))
        {
            // Get movie title
            if(line.find('(') != std::string::npos)
            {
                title = line.substr(0, line.find('(')-1);
            }

            // Get movie year
            if (line.find('(') != std::string::npos) {
                year = line.substr(line.find('(') + 1, line.find(')'));
                year = year.substr(0, year.find(')'));
            }

            // Add to actors list
            actors.push_back(line);
        }
        else
        {
            if(!actors.empty()) // pops the title
            {
                actors.pop_front(); 
            }
        }
        tree.insert(title, year, actors);
        actors.clear();
        movies++;
    }
}

and

#include <iostream>
#include <list>
using namespace std;

class BST
{
    // Defines the main components of the node object, as well as refrences the left and right elements
    struct node
    {
        string show;
        string year;
        string genre;
        string URL;
        list <string> actors;
        node*left;
        node*right;
    };

    node* root;

    // Deletes all the nodes of the tree
    node* makeEmpty(node* t)
    {
        if(t == NULL)
        {
            return NULL;
        }
        else
        {
            makeEmpty(t->left);
            makeEmpty(t->right);
            delete t;
        }
        return NULL;
    }

    // Inserts a node in the tree
    node* insert(string x, string year, list<string> actors, node* t)// DO not include Genrem or URL
    {
        if(t == NULL)
        {
            t = new node;
            t->show = x;
            t->year = year;
            t->actors = actors;
            t->left = t->right = NULL;
        }
        else if(x < t-> show)
        {
            t->left = insert(x, year, actors, t->left);
        }
        else if(x > t-> show)
        {
            t->right = insert(x, year, actors, t->left);
        }
        else
        {
            return t;
        }
    }

    //Finds the minimum most node to the left
    node* findMin(node* t)
    {
        if(t == NULL)
        {
            return NULL;
        }
        else if(t->left == NULL)
        {
            return t;
        }
        else
        {
            return findMin(t->left);
        }
    }

    // Finds the maximum most node to the right
    node* findMax(node* t)
    {
        if(t == NULL)
        {
            return NULL;
        }
        else if(t->right == NULL)
        {
            return t;
        }
        else
        {
            return findMax(t->right);
        }
    }

    // Finds a node with the given parameters
    node* find(node* t, string x )
    {
        if(t == NULL)
        {
            return NULL;
        }
        else if(x.at(0) < t-> show.at(0))
        {
            return find(t->left, x);
        }
        else if(x.at(0) > t->show.at(0))
        {
            return find(t->right, x);
        }
        else
        {
            return t;
        }
    }

    // Prints out the shows inorder
    void inorder(node* t)
    {
        if(t == NULL)
        {
            // Do nothing
        }
        else
        {
            inorder(t->left);
            cout << "- " << t->show << endl;
            inorder(t->right);
        }
    }

    // Prints the shows of a given actor
    void findShow(node* t, string person, list<string> &list)
    {
        if(t == NULL)
        {
            // Do nothing
        }
        else
        {
            while(!t->actors.empty())
            {
                if(t->actors.front() == person)
                {
                    list.push_front(t->show);
                    break;
                }
                t->actors.pop_front();
            }
            findShow(t->left, person, list);
            findShow(t->right, person, list);

        }
    }

    // Prints the shows within a given year
    void findYear(node* t, string year, list<string> &list)
    {
        if(t == NULL)
        {
            // Do nothing
        }
        else
        {
            if(t->year == year)
            {
                list.push_front(t->show);
            }
            findYear(t->left, year, list);
            findYear(t->right, year, list);
        }

    }
public:
    BST()
    {
        root = NULL;
    }

    ~BST()
    {
        root = makeEmpty(root);
    }

    // Public calls to modify the tree

    // Inserts a node with the given parametersremove
    void insert(string x, string year, list<string> actors)
    {
        root = insert(x, year, actors, root);
    }

    // Removes a node with the given key
    // void remove(string x, node* t)
    // {
    //     root = remove(x, root);
    // }


    // Displays all shows within the tree
    void displayShows()
    {
        inorder(root);
    }

    // Displays all the actors with a given show
    void displayActors(string show)
    {
        root = find(root, show);
        if(root != NULL) // THIS LINE
        {
            list<string> temp = root-> actors;
            while(!temp.empty())
            {
                cout << "- " << temp.front() << endl;
                temp.pop_front();
            }
        }
        else 
        {
            cout << "root is NULL." << endl;
        }
    }

    // Displays the shows of a given actor
    void displayActorsShows(string actor)
    {
        list<string> show;
        findShow(root, actor, show);
        while(!show.empty())
        {
            cout << "- " << show.front() << endl;
            show.pop_front();
        }
    }

    // Searches the tree with the given node
    void search(string x)
    {
        root = find(root, x);
    }
};// end of class
FroyoJones
  • 41
  • 6
  • 1
    Have you tried running in a debugger to let it catch the crash as it happens? It will help you find where in your code it happens, and also examine variables and their values at the time of the crash. – Some programmer dude Apr 20 '20 at 08:50
  • Thats a great idea – FroyoJones Apr 20 '20 at 08:54
  • Why does `makeEmtpy` need to return a value (and always return NULL)? – selbie Apr 20 '20 at 08:59
  • 1
    Isn't your compiler screaming bloody murder that three of the four cases of `insert` do not return a value? – Botje Apr 20 '20 at 09:00
  • The most likely candidate for the problem is mentioned by @Botje. If your compiler doesn't complain about it now, then enable more warnings and treat them as errors. Assuming you use `g++` to build, I recommend you add at least `-Wall -Wextra .Wpedantic` when building your code. – Some programmer dude Apr 20 '20 at 09:07
  • Recursive functions work exactly like non-recursive functions - you must return something in every case. You got this right with the other recursive functions, so it looks like you changed your mind in the middle of implementing `insert`, or wrote an `else` too many by accident. – molbdnilo Apr 20 '20 at 09:10

1 Answers1

2

I would suggest using a debugger (like GDB for unix or the VisualStudioBuildIn Debugger). There the SEG Fault is indicated in which variable the seg fault will be. Also look out for correct initialized pointers (at least with = nullptr)

Btw: try to use nullptr instead of NULL, since it is not typesafe to use NULL. Here is why: NULL vs nullptr (Why was it replaced?)