difficulty inserting into binary search tree - c++

I am currently learning C++ and have been researching BST. I took upon myself a task within a workbook but have been struggling to finish the implementation.
I am not allowed to change the header file or any of the function definitions but I am allowed to add helpers.
I have attempted adding some helpers, but whenever I run the test file, no words are inserted into the tree.
I was hoping someone would be able to help me or give me guidance on finishing the implementation.
Any help on the other functions would be greatly appreciated!
My Header File:
#pragma once
#include <iostream>
#include <string>
// Node of the tree
struct Node
{
std::string data;
Node *left = nullptr;
Node *right = nullptr;
};
class BST
{
private:
Node *root = nullptr;
public:
BST();
BST(std::string word);
BST(const BST &rhs);
~BST();
void insert(std::string word);
void remove(std::string word);
bool exists(std::string word) const;
std::string inorder() const;
std::string preorder() const;
std::string postorder() const;
bool operator==(const BST &other) const;
bool operator!=(const BST &other) const;
};
My BST file:
#include "bst.h"
#include <iostream>
#include <string>
using namespace std;
string HelperInsert(Node **root, std::string word)
{
if (*root == nullptr)
{
// Create new node
*root = new Node;
// Set new value
(*root)->data = word;
// Set branches to nullptr
(*root)->left = nullptr;
(*root)->right = nullptr;
}
else
if (word < (*root)->data)
{
HelperInsert(&(*root)->left, word);
}
else
{
if (word > (*root)->data)
{
HelperInsert(&(*root)->right, word);
}
}
}
void HelperExists(Node *root, string word)
{
Node *temp = new Node;
temp = root;
// Run the loop untill temp points to a NULL pointer.
while(temp != NULL)
{
if(temp->data == word)
{
cout<<"True "<<endl;
}
// Shift pointer to left child.
else if(temp->data > word)
temp = temp->left;
// Shift pointer to right child.
else
temp = temp->right;
}
cout<<"\n False";
return;
}
string Helpwr(Node *root)
{
if(root == nullptr)
{
return "";
}
else
{
return inorderHelper(root->left)
+ root->data + " "
+ inorderHelper(root->right);
}
}
void HelperPreOrder(Node *root)
{
if ( root !=nullptr)
{
cout << root->data << " ";
HelperPreOrder(root->left);
HelperPreOrder(root->right);
}
}
void HelperPostorder(Node *root)
{
if (root!=nullptr)
{
HelperPostorder(root->left);
HelperPostorder(root->right);
cout << root->data<< endl;
return;
}
}
BST::BST()
{
root= nullptr;
}
// Creates a binary tree by copying an existing tree
BST::BST(const BST &rhs)
{
}
void BST::insert(string word)
{
HelperInsert(*root, word);
}
void BST::remove(string word)
{
}
bool BST::exists(string word) const
{
HelperExists(root, word);
return true;
}
std::string BST::inorder() const
{
string res = inorderHelper(root);
int len = res.length();
if(len >= 1 && res[len -1] == ' ')
{
res.pop_back();
}
return res;
}
std::string BST::preorder() const
{
HelperPreOrder(root);
return std::string("");
}
std::string BST::postorder() const
{
HelperPostorder(root);
return std::string("");
}
bool BST::operator==(const BST &other) const
{
return true;
}
bool BST::operator!=(const BST &other) const
{
return true;
}
My test file:
tree = new BinarySearchTree();
// Test 3 - insertion check
tree->insert("fish");
tree->insert("aardvark");
tree->insert("zeebra");
str = tree->inorder();
if (str != string("aardvark fish zeebra"))
cerr << "test 3 failed" << endl;
else
cout << "Test 3 passed" << endl;
// Test 4 - exists check
if (tree->exists("zeebra") && tree->exists("fish") && !tree->exists("bird") && !tree->exists("snake"))
cout << "Test 4 passed" << endl;
else
cerr << "test 4 failed" << endl;

Seems like an issue of not storing the string words correctly:
your insert method is as follows:
void insert(std::string word);
Which means a value of the string is passed, not a reference.
In order to store the string, you'll have to create a copy of the string and store it in memory:
string HelperInsert(Node **root, std::string word)
{
if (*root == nullptr)
{
// Create new node
*root = new Node;
// Set new value
(*root).data = new std:string(word); // note the setting of a string pointer here!
// Set branches to nullptr
(*root)->left = nullptr;
(*root)->right = nullptr;
}
else
if (word < (*root)->data)
{
HelperInsert(&(*root)->left, word);
}
else
{
if (word > (*root)->data)
{
HelperInsert(&(*root)->right, word);
}
}
}
Do not forget to delete the string when removing nodes, in order to prevent mempory leaks.
Good luck!

Related

Cannot find source of segmentation fault

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
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?)

C++ Binary Tree With 3 Values For Struct

So I am attempting to create a binary search tree that stores an ID (T value) an age (int age) and a name (string) per each "bubble" located within the tree and is sorted by the ID.
For some reason, I cannot get my code to correctly store all 3 values as 1 structure per node. Is there something I am doing wrong?
Here's my code.
#ifndef _TREE_GUARD
#define _TREE_GUARD 1
#include <iostream>
#include <math.h>
using namespace std;
template <class T>
struct Node {
T value;
int age;
string name;
Node *left;
Node *right;
Node(T val) {
this->value = val;
}
Node(T val, int age, string name, Node<T> left, Node<T> right) {
this->value = val;
this->age = age;
this->name = name;
this->left = left;
this->right = right;
}
};
template <class T>
class BST {
private:
Node<T> *root;
void addHelper(Node<T> *root, T val) {
if (root->value > val) {
if (!root->left) {
root->left = new Node<T>(val);
}
else {
addHelper(root->left, val);
}
}
else {
if (!root->right) {
root->right = new Node<T>(val);
}
else {
addHelper(root->right, val);
}
}
}
void printHelper(Node<T> *root) {
if (!root) return;
printHelper(root->left);
cout << root->value << ' ';
cout << root->age << ' '; // ADDED
cout << root->name << ' '; //ADDED
printHelper(root->right);
}
int nodesCountHelper(Node<T> *root) {
if (!root) return 0;
else return 1 + nodesCountHelper(root->left) + nodesCountHelper(root->right);
}
int heightHelper(Node<T> *root) {
if (!root) return 0;
else return 1 + max(heightHelper(root->left), heightHelper(root->right));
}
void printMaxPathHelper(Node<T> *root) {
if (!root) return;
cout << root->value << ' ';
if (heightHelper(root->left) > heightHelper(root->right)) {
printMaxPathHelper(root->left);
}
else {
printMaxPathHelper(root->right);
}
}
bool deleteValueHelper(Node<T>* parent, Node<T>* current, T value) {
if (!current) return false;
if (current->value == value) {
if (current->left == NULL || current->right == NULL) {
Node<T>* temp = current->left;
if (current->right) temp = current->right;
if (parent) {
if (parent->left == current) {
parent->left = temp;
}
else {
parent->right = temp;
}
}
else {
this->root = temp;
}
}
else {
Node<T>* validSubs = current->right;
while (validSubs->left) {
validSubs = validSubs->left;
}
T temp = current->value;
current->value = validSubs->value;
validSubs->value = temp;
return deleteValueHelper(current, current->right, temp);
}
delete current;
return true;
}
return deleteValueHelper(current, current->left, value) ||
deleteValueHelper(current, current->right, value);
}
public:
void insert(T val) {
if (root) {
this->addHelper(root, val);
}
else {
root = new Node<T>(val);
}
}
void print() {
printHelper(this->root);
}
int nodesCount() {
return nodesCountHelper(root);
}
int height() {
return heightHelper(this->root);
}
void printMaxPath() {
printMaxPathHelper(this->root);
}
bool Delete(T value) {
return this->deleteValueHelper(NULL, this->root, value);
}
};
#endif
I created the struct using these 3 values, and a pointer to a right and left node, however, all my other functions don't seem to work with the age and name values, only the ID. This is most problamatic in my add and print function.
I'm relatively new to C++, so any help would be appreciated.
EDIT: I'm assuming my problem lies around here somewhere. The code runs just fine, but it doesn't add the age and name to the string, and I can't properly print these values, just the ID
Node<T> *root;
void addHelper(Node<T> *root, T val) {
if (root->value > val) {
if (!root->left) {
root->left = new Node<T>(val);
}
else {
addHelper(root->left, val);**
}
}
else {
if (!root->right) {
root->right = new Node<T>(val);
}
else {
addHelper(root->right, val);
}
}
}
and here
void printHelper(Node<T> *root) {
if (!root) return;
printHelper(root->left);
cout << root->value << ' ';
cout << root->age << ' '; // ADDED
cout << root->name << ' '; //ADDED
printHelper(root->right);
}
Thanks in advance!
root->left = new Node(val);
root->right = new Node(val);
It seems that you create a new node and only give it a "val", no age, no name etc, so it only has the value.
edit: I never used "Template" before, so it took me a while to figure it out. Anyways...
Solution:
When you insert a node, you need to copy all the information, not just the "value", otherwise you'll only get the "value".
void addHelper(Node<T> *root, Node<T>* n) {
if (root->value > n->value) {
if (!root->left) {
root->left = new Node<T>(n->value,n->age,n->name,NULL,NULL);
}
else {
addHelper(root->left, n);
}
}
else {
if (!root->right) {
root->right = new Node<T>(n->value,n->age,n->name,NULL,NULL);
}
else {
addHelper(root->right, n);
}
}
}
Also in "insert":
void insert(Node<T>* n) {
if (root) {
this->addHelper(root, n);
}
else {
root = new Node<T>(n->value,n->age,n->name,NULL,NULL);
}
}
Several other things you may try and see the difference:
I would initialize *root to be NULL, otherwise it may be some random stuff, and sometime I got seg fault because of that.
class BST {
private:
Node<T> *root=NULL;
If the node you're about to insert has the same "value" with an already existing node, what do you do? Your program will just add it to the right. I don't know if that's what you want, but that's what it will do.
I tested with this and it worked. Hope it will work for you, too.
int main(){
BST<int> tree;
Node<int> node1(1,10,"test1",NULL,NULL);
Node<int> node2(5,50,"test2",NULL,NULL);
Node<int> node3(3,30,"test3",NULL,NULL);
Node<int> node4(3,30,"test4",NULL,NULL);
Node<int> node5(3,30,"test5",NULL,NULL);
Node<int> node6(8,80,"test5",NULL,NULL);
tree.insert(&node1);
tree.insert(&node2);
tree.insert(&node3);
tree.insert(&node4);
tree.insert(&node5);
tree.insert(&node6);
tree.print();
cout<<endl;
return 0;
}
output:
1 10 test1 3 30 test3 3 30 test4 3 30 test5 5 50 test2 8 80 test5

my program crashes after running

well this is my code and basically what i am trying to do is for my program to take words out of a text file that i prepared and to pass it to my program and count the amount of unique words, and to print out the unique word with the count on the side of it. i have cleared up all the errors i had but now i am stuck as it crashes every time i try to run it.
i would appreciate if someone could enlighten me on where i have done wrong on.
#include <iostream>
#include <cstdlib>
#include <fstream>
using namespace std;
class BST
{
public:
BST ();
void insert (char*);
void printBST () const;
bool findNode (char*) const;
private:
struct Node;
typedef Node* NodePtr;
struct Node
{
char *word;
int count;
NodePtr left, right;
};
NodePtr root;
int compareVP (char*, char*) const;
void insert (NodePtr&, char*);
void inorderPrint (NodePtr) const;
bool findNode (NodePtr, char*) const;
};
int main ()
{
BST t;
char word[25];
ifstream readfile("infile.txt");
if(!readfile)
{
cout << "File could not be opened/found";
return 0;
}
while(readfile>> word)
{
t.insert(word);
}
if(readfile.eof())
t.printBST ();
}
BST::BST ()
{
root = NULL;
}
void BST::insert (char* word)
{
insert (root, word);
}
void BST::printBST () const
{
inorderPrint (root);
}
bool BST::findNode (char* word) const
{
return findNode (root, word);
}
int BST::compareVP (char* item1, char* item2) const
{
char* value1 = item1;
char* value2 = item2;
if (strcmp(value1,value2)==0)
return 0;
else if (strcmp(value1,value2)>0)
return 1;
else
return -1;
}
void BST::insert (NodePtr& root, char* word)
{
if (root == NULL)
{
NodePtr temp = new Node;
temp -> word = word;
temp -> left = NULL;
temp -> right = NULL;
root = temp;
}
else if (compareVP (root -> word, word) > 0)
insert (root -> left, word);
else if (compareVP (root -> word, word) < 0)
insert (root -> right, word);
else if (compareVP (root -> word, word) == 0)
root -> count++;
}
void BST::inorderPrint (NodePtr root) const
{
cout << "Word\tCount\n";
if (root != NULL)
{
inorderPrint (root -> left);
cout << root -> word << "\t";
cout << root -> count << "\n";
inorderPrint (root -> right);
}
else
cout << endl;
}
bool BST::findNode (NodePtr root, char* word) const
{
if (root == NULL)
return false;
else
{
int k = compareVP (root -> word, word);
if (k == 0)
return true;
else if (k > 0)
return findNode (root -> left, word);
else
return findNode (root -> right, word);
}
}
One problem here:
char* word; // Pointer contains reference to undef areal of memory
while(readfile >> word) // you trying save line to undef area - result is unpredictable
2nd problem:
In function insert() you just attach to node pointer, and reuse this pointer on levels upper.
Possible simple solution:
char word[1000];
while(readfile >> word)
{
t.insert(strdup(word));
}
Changed print method. and a line for the insertion.
#include <iostream>
#include <cstdlib>
#include <fstream>
using namespace std;
class BST
{
public:
BST ();
void insert (char*);
void printBST () const;
bool findNode (char*) const;
private:
struct Node;
typedef Node* NodePtr;
struct Node
{
char *word;
int count;
NodePtr left, right;
};
NodePtr root;
int compareVP (char*, char*) const;
void insert (NodePtr&, char*);
void inorderPrint (NodePtr) const;
bool findNode (NodePtr, char*) const;
};
int main ()
{
BST t;
char word[25];
ifstream readfile("infile.txt");
if(!readfile)
{
cout << "File could not be opened/found";
return 0;
}
while(readfile>> word)
{
t.insert(strdup(word));
}
if(readfile.eof())
t.printBST ();
}
BST::BST ()
{
root = NULL;
}
void BST::insert (char* word)
{
insert (root, word);
}
void BST::printBST () const
{
cout << "Word\tCount\n";
inorderPrint (root);
}
bool BST::findNode (char* word) const
{
return findNode (root, word);
}
int BST::compareVP (char* item1, char* item2) const
{
char* value1 = item1;
char* value2 = item2;
if (strcmp(value1,value2)==0)
return 0;
else if (strcmp(value1,value2)>0)
return 1;
else
return -1;
}
void BST::insert (NodePtr& root, char* word)
{
if (root == NULL)
{
NodePtr temp = new Node;
temp -> word = word;
temp -> left = NULL;
temp -> right = NULL;
temp -> count = 1;
root = temp;
}
else if (compareVP (root -> word, word) > 0)
insert (root -> left, word);
else if (compareVP (root -> word, word) < 0)
insert (root -> right, word);
else if (compareVP (root -> word, word) == 0)
root -> count++;
}
void BST::inorderPrint (NodePtr root) const
{
if (root != NULL)
{
inorderPrint (root -> left);
cout << root -> word << "\t";
cout << root -> count;
inorderPrint (root -> right);
}
else
cout << endl;
}
bool BST::findNode (NodePtr root, char* word) const
{
if (root == NULL)
return false;
else
{
int k = compareVP (root -> word, word);
if (k == 0)
return true;
else if (k > 0)
return findNode (root -> left, word);
else
return findNode (root -> right, word);
}
}

Binary Search Tree Issue in C++

i am creating a binary search tree, and here is my code for the TreeDB.cpp file:
TreeDB::TreeDB()
{
root = NULL;
}
bool TreeDB::insert(DBentry * _entry)
{
if (root == NULL)
{
root = new TreeNode(_entry);
root->setLeft(NULL);
root->setRight(NULL);
cout <<"Inserted at root";
}
else
{
insert_helper(root,_entry);
}
}
bool TreeDB::insert_helper(TreeNode *curr, DBentry * _entry)
{
string temp1 = curr->getEntry()->getName();
string temp2 = _entry-> getName();
if(temp1 == temp2)
{
cout <<"Error: entry already exists"<<endl;
delete _entry;
return false;
}
else if(temp1<temp2)
{
if(curr->getRight() == NULL)
{
curr->setRight(new TreeNode(_entry));
cout << "Set right";
return true;
}
else
{
insert_helper(curr->getRight(),_entry);
}
}
else
{
if(curr->getLeft() == NULL)
{
curr->setLeft(new TreeNode(_entry));
cout <<"Set Left";
return true;
}
else
{
insert_helper(curr->getLeft(),_entry);
}
}
}
and my header file is Tree.h:
class TreeDB {
private:
TreeNode* root;
int probesCount;
public:
TreeDB();
~TreeDB();
bool insert(DBentry* newEntry);
bool insert_helper(TreeNode*curr,DBentry*_entry);
};
And i am also creating the object of this tree in main like so:
TreeDB Tree;
while (!lineStream.eof())
{
if (command == "insert")
{
unsigned int address;
string name;
bool active;
lineStream >> name >> address >> active;
DBentry * a = new DBentry(name,address,active);
Tree.insert(a);
}
However, every time i try to insert something, it always inserts at the root, so either the previous one never gets saved or it gets deleted after each insert. Any hints as to how i can resolve this issue?

what happen to my code?

I am new to C++. I am really confused between C and C++. I am familair with C and java, but not C++. Today I am going to write a linked list program using C++. But to what happened to my code ???
Thanks.
Raymond
the result:
Unhandled exception at 0x00412656 in 09550978d.exe: 0xC0000005: Access violation writing location 0xcdcdcdcd.
#include <iostream>
#include <string>
using namespace std;
struct word
{
bool empty;
string name;
int count;
word* next;
};
typedef struct word word;
word* create(word* theList)
{
word* head = (word*)malloc(sizeof(word));
head->empty = false;
head->name = "";
head->next = 0;
return head;
}
void print(word* theList)
{
word* current = theList;
while(current!=0)
{ cout << current->name << " : " << current->count << " \n" ;
current = current->next;
}
}
void add(string myString, word* theList)
{
//word* newWord = (word*)malloc(sizeof(word));
if( theList->empty == false )
{
theList->empty = true;
theList->name = myString;
theList->next = 0;
}
else
{
word* current = theList;
while(current->next!=0)
{
current = current->next;
}
word* newWord = (word*)malloc(sizeof(word));
newWord->empty = true;
newWord->name = myString;
newWord->next = 0;
current->next = newWord;
}
}
int main(void)
{
word* theList = 0;
theList = create(theList);
add("Hello", theList);
//add("world", theList);
}
#include <iostream>
#include <string>
using namespace std;
class word
{
public:
string name;
int count;
word *next;
word (string name);
};
word::word (string myName)
{
name = myName;
next = NULL;
count = 1;
}
class List
{
public:
bool isEmpty;
word* theHead;
List();
List(word* aHead);
void print();
void add(string myString);
void search(string myString);
};
List::List()
{
isEmpty = true;
}
List::List(word* aHead)
{
isEmpty = false;
theHead = aHead;
}
void List::add(string myString)
{
word* newWord = new word(myString);
if (isEmpty == true)
{
isEmpty = false;
theHead = newWord;
}
else
{
word* current = theHead;
if ( current->next == NULL)
{
if( myString.compare(current->name) == 0 )
{
current->count = current->count + 1;
return;
}
}
else
{
while ( current->next != NULL )
{
if( myString.compare(current->name) == 0 )
{
current->count = current->count + 1;
return;
}
current = current->next;
}
}
current->next = newWord;
}
}
void List::print ()
{
if (isEmpty)
{
cout << "nothing in the list";
}
else
{
word* current = theHead;
while(current != NULL)
{
cout << current->name << " : " << current->count << " \n" ;
current = current->next;
}
}
}
void List::search(string myString)
{
if (isEmpty)
{
cout << "The word : " << myString << " is not in the List.\n";
}
else
{
word* current = theHead;
while( current != NULL )
{
if( myString.compare(current->name) == 0 )
{
cout << "The word : " << myString << " is in the List.\n";
return;
}
else
{
current = current->next;
}
}
cout << "The word : " << myString << " is not in the List.\n";
}
return;
}
int main(void)
{
List theList = List();
string str1 = "Hello";
string str2 = "world";
theList.add(str1);
theList.add(str2);
theList.add(str1);
theList.search("Hello");
theList.search("You");
theList.print();
int i;
scanf("%d", &i);
}
You should be using the new operator instead of malloc. See the difference here. Also why use structs and typedefs when c++ allows you to make a class
Here is my version of your code, its not bug free yet but it should illustrate how to use new and classes. I will try to fix it fully and update you.
Also note that within the class structure of c++ you automatically get a this pointer with member functions that acts as a pointer to the class, so you no longer have to pass in word* theList
Edit: I updated with working code, the only thing that doesn't work is the count aspect to the list. Otherwise notice that there are two classes, List interfaces with word to create a linked list, I have not included any memory management aspects to the code (which would not be so hard using the c++ destructor, if you need such facilities please indicate so in the comments, and I will be sure to add.
#include <iostream>
#include <string>
using namespace std;
class word
{
public:
string name;
int count;
word *next;
word (string name);
};
word::word (string myName)
{
name = myName;
next = NULL;
count = 0;
}
class List
{
public:
bool isEmpty;
word* theHead;
List();
List(word* aHead);
void print();
void add(string myString);
};
List::List()
{
isEmpty = true;
}
List::List(word* aHead)
{
isEmpty = false;
theHead = aHead;
}
void List::add(string myString)
{
word* newWord = new word(myString);
if (isEmpty == true)
{
isEmpty = false;
theHead = newWord;
}
else
{
word* current = theHead;
while(current->next != NULL)
{
current = current->next;
}
current->next = newWord;
}
}
void List::print ()
{
if (isEmpty)
{
cout << "nothing in the list";
}
else
{
word* current = theHead;
while(current != NULL)
{
cout << current->name << " : " << current->count << " \n" ;
current = current->next;
}
}
}
int main(void)
{
List theList = List();
string str1 = "Hello";
string str2 = "world";
theList.add(str1);
theList.add(str2);
theList.print();
}
Edit: Here is the destructor to free the allocated memory, make sure to add the prototype ~List() in the class declaration:
List::~List()
{
if (!isEmpty)
{
word* prev = NULL;
word* current = theHead;
while(current != NULL)
{
prev = current;
current = current->next;
delete prev;
}
}
}
Hope this helps.
Most obvious problem: use new and not malloc to allocate new objects: malloc doesn't call constructor and one design principle of C++ is that constructors are called before any other operations on an object.
BTW, you code look like C using only the most basic C++ features. It would never be written like this by someone knowing C++ (word would have a constructor and private member, even for people using C++ as a "better C").
For one, in Add function
if( theList->empty == false )
{
theList->empty = true;
theList->name = myString;
theList->next = 0;
}
should be opposite - if list->empty == true, then set it to false.
As for the unhandled exception, a simple step by step 5 minute debugging session will both help you find your errors and will make you like and use the debugger. I mean it. DO TRY DEBUGGING!!!
my2c