Run Time Error with Hash Program using Separate Chaining

I have a run time error when I instantiate an object in a PhoneBook class which is an array of doubly linked lists. The code is shown below and the error one line after a comment which says ERROR BELOW. I would appreciate any help. This is just a personal exercise I am doing that I obtained from the internet. Thank you.

#include <iostream>
#include <stdlib.h>

using namespace std;

// Person: name and phone number
class Person
{

public:
// initialize name and phone number, assuming phone is PHONELEN digits
//constructor define the Person object
Person(const char name[], const char phone[])
{
// phone is 10 characters plus \0
// person is 15 characters plus \0

if (strlen(name) <= NAMELEN) { strcpy(this->name, name); }
else { cout << "name was greater than size limit of 15 char" << endl; }

if (strlen(phone) <= PHONELEN) { strcpy(this->phone, phone); }
else { cout << "name was greater than size limit of 10 char" << endl; }
}

// return true if OTHER's phone number is the same as this one
bool samePhone(const Person *other) const
{
if (strcmp(this->name, other->getName()) == 0) { return true; } // same name
else { return false; }
}

// return hash value for object as an integer between 0 and 99 (inclusive)
int Person::hashValue() const
{
char cDig1, cDig2;
cDig1 = phone[8];
cDig2 = phone[9];

int dig1, dig2, result;
dig1 = int(cDig1 - '0');
dig2 = int(cDig2 - '0');
result = 10*dig1 + dig2;

return result%101;
}

// return name field
const char* getName() const
{
return name;
}

enum { NAMELEN = 81, PHONELEN = 10 };
protected:
char name[NAMELEN]; // null-terminated string
char phone[PHONELEN]; // *not* null-terminated
};

// PersonList: a linked list of Person objects
class PersonList
{
private:
static unsigned int count;
char name[Person::NAMELEN]; // null-terminated string
char * name2;
char phone[Person::PHONELEN]; // *not* null-terminated

Person * aPerson;

struct PersonNode
{
Person *person;
PersonNode *prev, *next;
PersonNode::PersonNode(Person *pers, PersonNode *n, PersonNode *p)
: person(pers), next(n), prev(p)
{ }
} *front, *back;
PersonList(const PersonList&) // hide copy constructor
{}

void operator=(const PersonList&) // hide assignment operator
{}

bool empty() const { return ( !front || !back ); } // quick inline function to determine if list is empty

public:
// initialize list to be empty
PersonList()
:front(NULL), back(NULL)
{
char * tempName = "JoeSmith";
char * tempPhone = "1234561234";
strcpy(name, tempName);
strcpy(phone, tempPhone);
aPerson = new Person(name, phone);
}

// remove all entries from the list, deleting the entries as well
~PersonList()
{
while(front)
{
PersonNode * temp = front;
front = front->next;
delete temp;
}
}

// add: add NEW_PERSON to front of list; assumes NEW_PERSON not already
// in the list
void add(Person *new_person)
{
// ERROR BELOW, occurs on next line front =
front = new PersonNode(new_person, front , NULL); //previous is NULL, next is current front
count++;
if(front->next)
{
front->next->prev = front;
}

if ( empty() )
{
back = front;
}
}


// lookup: return object in list with same phone number as TARGET;
// also moves the found object to the front of the list
Person *lookup(const Person *target)
{
PersonNode * current = front;
while(current)
{
if(current->person->samePhone(target))
{
if (current==front)
{
return current->person;
}
else if (current == back)
{
PersonNode * objectToMove = current;
back = current->prev; //#1
current->prev->next = NULL; //#2
front->prev = objectToMove; //#3
objectToMove->prev = NULL; //#4
objectToMove->next = front; //#5
front = objectToMove; //#6
return objectToMove->person;
}
else
{
PersonNode * objectToMove = current;
current->prev->next = current->next; //#1 First take care of items
current->next->prev = current->prev; //#2
front->prev = objectToMove; //#3
objectToMove->prev = NULL; //#4
objectToMove->next = front; //#5
front = objectToMove; //#6
return objectToMove->person;
}
} // end current->person->samePhone(target)
current = current->next;
} // end of while
return NULL;
} // end of lookup

// remove: remove TARGET from the list; does nothing if there is no pointer
// in the list equal to TARGET
void remove(const Person *target)
{
PersonNode * current = front;

while(current)
{ //if(current->person->samePhone(target))
if(current->person == target )
{
if (current==front)
{
current->next->prev = NULL;
front = current->next;
//cout << current->person->getName() << " with number " << current->
delete current;
count--;
break;
}
else if (current == back)
{
current->prev->next = NULL;
back = current->prev;
delete current;
count--;
break;
}
else
{
current->prev->next = current->next;
current->next->prev = current->prev;
delete current;
count--;
break;
}
} //end if current==front
current = current->next;
} // end while
} // end of remove

// length: return number of entries on list
int length() const
{
return count;
}
};

unsigned int PersonList::count = 0;

class RevPhoneBook
{
private:
static unsigned int count;
PersonList * personListPtr[101];
PersonList oneList;
public:
RevPhoneBook()
{}

~RevPhoneBook()
{
delete [] personListPtr;
}

void add(Person* new_person)
{
int locationOfPerson = new_person->hashValue();
count++;
personListPtr[locationOfPerson]->add(new_person);
}

Person* lookup(const Person* target)
{
for (int j=0; j<count; j++)
{
if(personListPtr[j]->lookup(target))
{
return personListPtr[j]->lookup(target);
}
}
}

void remove(const Person* target)
{
for (int j=0; j<count; j++)
{
if(personListPtr[j]->lookup(target) == target)
{
personListPtr[j]->remove(target);
}
}
}
};
unsigned int RevPhoneBook::count = 0;


int main()
{

{
Person adrian("adrian", "111");
Person carlos("carlos", "123");
Person tom("tom", "972");
Person jack("jack", "682");
Person miguel("miguel", "956");

RevPhoneBook myPhoneBook;
myPhoneBook.add(&adrian); //RUN TIME ERROR OCCURS HERE!!
// LOOK AT NOTES ABOVE in add
}
return 1;
}


http://www.cplusplus.com/articles/iwTbqMoL/

Bad value of locationOfPerson
I know where the error is as I pointed it out below:

// ERROR BELOW, occurs on next line front =
front = new PersonNode(new_person, front , NULL); //previous is NULL, next is current front

I just need to know how to fix this. Do I need to change PersonNode so that it works or can I use it as it is because I dont know how to instantiate PersonNode properly?
I know where the error is as I pointed it out below:

No, you do not know. The line you pointed out is where you are using an erroneous value that causes a segFault. It is not the line that creates the erroneous value.

You need to change the function Person::hashValue() so it returns a value that is between zero and 100.
Last edited on
That was a good catch. My program is setup for people entering 10 digit numbers like we use in USA(area code plus 7 digits). I only entered 3 digits. I have re-written my main so it now uses 10 digit numbers but it still has problems at the line mentioned. If you are able to help I would I appreciate it.

The value I get hashValue is 46.
Main changes below.
Person adrian("adrian", "9565420346");
Person carlos("carlos", "7171234567");
Person tom("tom", "9721234567");
Person jack("jack", "6821234567");
Person miguel("miguel", "9561234567");

RevPhoneBook myPhoneBook;
myPhoneBook.add(&adrian); //RUN TIME ERROR OCCURS HERE!!

Again, error as shown in comment.
This is the classical 'which came first the chicken or the egg problem'.
It breaks down because it has a null pointer of type PersonNode, but there is I don't know of way to create a PersonNode. Should I feed it a char location that is typecast to PersonNode?

Thanks again.
Last edited on
Topic archived. No new replies allowed.