C++ crashing when passing pointer to function - c++

what i am trying to do is display my pointer to an array of objects. here is my main program, the function it crashes at is listAll(). if i only enter one object it works, but when i enter a second one it crashes. i am at a loss of what is going wrong. problem occurs after picking menuOption 1 twice and then trying to call list all. i see that the array size is not being increased..
#include <fstream>
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
#include "fileStuff.h"
bool menu();
bool menuOptions(int option);
void fileIO();
void listAll(interact * obs, int arryO);
int main()
{
bool isRunning = true;
while (isRunning)
{
isRunning = menu();
}
return 0;
}
bool menu()
{
int option = 0;
cout << "1: add new backpack. " << endl
<< "2: delete a backpack "<< endl
<< "3: sort ascending by id " << endl
<< "4: sort descending by id " << endl
<< "5: list all backpacks " << endl
<< "6: quit" << endl;
cin >> option;
return menuOptions(option);
}
bool menuOptions(int option)
{
static int arrayO = 0;
static interact *obs = new interact[arrayO];
fileStuff test;
int tempBagId = 0, tempInvSpaces = 0, tempAmtOfItemsInInv = 0;
double tempInvMaxWeight = 0.0;
string tempBagType, tempBagCondish;
int t = 0 ;
int i = 0;
switch (option)
{
case 1:
cout << "bagId? ";
cin >> tempBagId;
cout << "How many inv spaces? ";
cin >> tempInvSpaces;
cout << "How much weight can the bag hold? ";
cin >> tempInvMaxWeight;
(obs + arrayO)->setBagId(tempBagId);
(obs + arrayO)->setInvSpaces(tempInvSpaces);
(obs + arrayO)->setInvMaxWeight(tempInvMaxWeight);
cout << "all stored" << endl;
arrayO++;
break;
case 2:
//listmanager delete one
//arrayO--;
break;
case 3:
//sort ascending by id
break;
case 4:
//sort descending by id
break;
case 5:
//list all
listAll(obs, arrayO);
break;
case 6:
obs = NULL;
delete obs;
return false;
break;
default:
break;
}
}
void listAll(interact * obs, int arryO)
{
int i = 0;
cout << i << endl;
cout << arryO << endl;
}
below is the gists of my class.
#include "listManager.h"
#include <iostream>
#include <string>
using namespace std;
interact::interact()
{
bagId = 0;
invSpaces = 0;
invMaxWeigt = 0;
}
void interact::setBagId(int id)
{
bagId = id;
}
void interact::setInvSpaces(int spaces)
{
invSpaces = spaces;
}
void interact::setInvMaxWeight(double weight)
{
invMaxWeigt = weight;
}
int interact::getBagId()
{
return bagId;
}
int interact::getInvSpaces()
{
return invSpaces;
}
double interact::getInvMaxWeight()
{
return invMaxWeigt;
}

You have:
static int arrayO = 0;
static interact *obs = new interact[arrayO];
This will create a dynamic array of 0 length. As Ben stated, the pointer will never change.
The crash is probably caused by trying to access it after increasing the index (arrayO++;), after that it will just be accessing out of bounds memory.

Your obs points to an array with size zero:
static int arrayO = 0;
static interact *obs = new interact[arrayO];
and never is changed to point to anything larger.
Therefore every attempt to subscript it is an array overrun.

Related

Missing array element issue

This is part of a homework assignment I recently finished. I am required to use an array of structs to store a library of books by title and author. The code is working and running perfectly fine when sorting and displaying author or title alphabetically according to user input.
The only issue I run into is when it shows all books sorted alphabetically. There are 14 books total in the text file used with the assignment, but only 13 books show up when the show all (S) option is entered.
An example of the error would be:
()
Audio for Games (Brandon)
Instead of:
Audio for Games (Brandon)
Beginning LINUX Programming (Stones and Matthew)
My Code:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
// structure
struct Book {
string title;
string author;
};
const int ARRAY_SIZE = 1000;
Book books[ARRAY_SIZE];
string pathName;
ifstream lib;
// global variables
int loadData();
void showAll(int count);
void sortByTitle(int count, string title);
int main()
{
// initialised variables
int count = 0;
char selector = 'q', yesNoAnswer = 'n';
string name;
string title;
// asks user for file pathname
cout << "Welcome to Tommy's Library Database." << endl;
cout << "Please enter the name of the file: ";
getline(cin, pathName);
loadData();
count = loadData();
cout << count << " Records loaded successfully." << endl;
// Switch case menu
do {
cout << endl << "Please enter a keyword that corresponds to the list of options: " << endl;
cout << " Search by: (A)uthor, (T)itle, (S)how All, (Q)uit Program: ";
cin >> selector;
selector = toupper(selector);
switch (selector)
{
case 'S':
sortByTitle(count, title);
if (count <= 0) {
cout << " No counts found! " << endl;
}
else {
showAll(count);
}
break;
}
}
while (selector != 'q' && selector != 'Q');
return 0;
}
int loadData()
{
int count = 0;
int i = 0;
lib.open(pathName);
ifstream lib(pathName);
if (!lib)
{
cout << " Unable to open file path! " << endl;
return -1;
}
while (!lib.eof())
{
getline(lib, books[count].title);
getline(lib, books[count].author);
count++;
}
return count;
}
// displays all book titles beside the author names
void showAll(int count)
{
for (int i = 0; i < count; i++)
{
cout << books[i].title << " " << "(" << books[i].author << ")" << endl;
}
}
// Sorts by book title.
void sortByTitle(int count, string title) {
Book temp;
for (int i = 0; i < count; i++) {
for (int j = 0; j < count - i; j++) {
if (books[j].title > books[j + 1].title) {
temp = books[j];
books[j] = books[j + 1];
books[j + 1] = temp;
}
}
}
}
The text file im using with the assignment (books.txt)
Objects First with Java
Barnes and Kolling
Game Development Essentials
Novak
The Game Maker's Apprentice
Overmars
C++ Programming: From Problem Analysis...
Malik
C++ Programming Lab Manual
Scholl
Beginning LINUX Programming
Stones and Matthew
C++ Programming: Program Design Including...
D. S. Malik
C++ How to Program
Deitel and Deitel
Programming and Problem Solving with C++
Dale, Weems, Headington
Game Character Development with Maya
Ward
Developing Games in Java
Brackeen
C# Programming
Harvey, Robinson, Templeman, Watson
Java Programming
Farrell
Audio for Games
Brandon
You were starting your loop from 0 inside your showAll() method when your books array starts from 1, just start the loop from 1 and go to count + 1
for (int i = 1; i < count + 1; i++)
Your sort function doesn't work correctly. It's off by one and moves an empty element to the first index. It would cause undefined behavior if your array were full. Your sort function sorts all elements from 0 to count but it should sort from 0 to count - 1. You should fix your sort function (std::sort usually is faster than bubble sort):
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
// structure
struct Book {
string title;
string author;
};
const int ARRAY_SIZE = 1000;
Book books[ARRAY_SIZE];
string pathName;
ifstream lib;
// global variables
int loadData();
void showAll(int count);
void sortByTitle(int count, string title);
int main()
{
// initialised variables
int count = 0;
char selector = 'q', yesNoAnswer = 'n';
string name;
string title;
// asks user for file pathname
cout << "Welcome to Tommy's Library Database." << endl;
cout << "Please enter the name of the file: ";
getline(cin, pathName);
loadData();
count = loadData();
cout << count << " Records loaded successfully." << endl;
// Switch case menu
do {
cout << endl << "Please enter a keyword that corresponds to the list of options: " << endl;
cout << " Search by: (A)uthor, (T)itle, (S)how All, (Q)uit Program: ";
cin >> selector;
selector = toupper(selector);
switch (selector)
{
case 'S':
sortByTitle(count, title);
if (count <= 0) {
cout << " No counts found! " << endl;
}
else {
showAll(count);
}
break;
}
}
while (selector != 'q' && selector != 'Q');
return 0;
}
int loadData()
{
int count = 0;
int i = 0;
lib.open(pathName);
ifstream lib(pathName);
if (!lib)
{
cout << " Unable to open file path! " << endl;
return -1;
}
while (!lib.eof())
{
getline(lib, books[count].title);
getline(lib, books[count].author);
count++;
}
return count;
}
// displays all book titles beside the author names
void showAll(int count)
{
for (int i = 0; i < count; i++)
{
cout << books[i].title << " " << "(" << books[i].author << ")" << endl;
}
}
// Sorts by book title.
void sortByTitle(int count, string title) {
std::sort(books, books + count, [](const auto &lhs, const auto &rhs) {
return lhs.title < rhs.title;
});
}
In addition:
You shouldn't read a stream with while (!lib.eof()): Why is iostream::eof inside a loop condition (i.e. while (!stream.eof())) considered wrong?
You can remove the first loadData()
You can remove the second parameter of void sortByTitle(int count)
You are shadowing global variables with local variables, e.g. global ifstream lib and local ifstream lib in int loadData()
You can remove unused variables
You should remove using namespace std;: Why is “using namespace std;” considered bad practice?
You should avoid global variables
You should replace endl by '\n' if you don't need to flush in that moment. endl does more than a simple linebreak and usually it's not necessary.
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using std::cin;
using std::cout;
using std::ifstream;
using std::string;
// structure
struct Book {
string title;
string author;
};
const int ARRAY_SIZE = 1000;
// global variables
int loadData(string pathName, Book *books);
void showAll(Book *books, int count);
void sortByTitle(Book *books, int count);
int main()
{
// initialised variables
int count = 0;
char selector = 'q';
// asks user for file pathname
cout << "Welcome to Tommy's Library Database.\n";
cout << "Please enter the name of the file: ";
string pathName;
getline(cin, pathName);
Book books[ARRAY_SIZE];
count = loadData(pathName, books);
cout << count << " Records loaded successfully.\n";
// Switch case menu
do {
cout << "\nPlease enter a keyword that corresponds to the list of options: \n";
cout << " Search by: (A)uthor, (T)itle, (S)how All, (Q)uit Program: ";
cin >> selector;
selector = toupper(selector);
switch (selector)
{
case 'S':
sortByTitle(books, count);
if (count <= 0) {
cout << " No counts found! \n";
}
else {
showAll(books, count);
}
break;
}
}
while (selector != 'q' && selector != 'Q');
return 0;
}
int loadData(string pathName, Book *books)
{
int count = 0;
ifstream lib(pathName);
if (!lib)
{
cout << " Unable to open file path! \n";
return -1;
}
while (getline(lib, books[count].title))
{
getline(lib, books[count].author);
count++;
}
return count;
}
// displays all book titles beside the author names
void showAll(Book *books, int count)
{
for (int i = 0; i < count; i++)
{
cout << books[i].title << " " << "(" << books[i].author << ")\n";
}
}
// Sorts by book title.
void sortByTitle(Book *books, int count) {
std::sort(books, books + count, [](const auto &lhs, const auto &rhs) {
return lhs.title < rhs.title;
});
}

program stopped working when I'm trying to input [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I'm working on a project, to create a linked list in class but I can't even start working on it because every time I run the program it's will stop working when I want to input data.
Can someone tell me how to input data properly using class? and if possible please let me know how to improve this program. The code that I've done is quite long.
I'll try to make it short and simple for you guys to understand. A lot of people been suggesting me to use std::string but our lecturer never mentioned about it so we have no idea how to use it.
If I have to use it that means I have to start learn it from the beginning which means it will take time for me to really understand it.
We're also required to have a function where we can update the data stored, search the data based on one of its data and make a summary for it.
#include <iostream>
#include <stdlib.h>
#include <cstdlib>
#include <conio.h>
#include <stdio.h>
#include <string>
using namespace std;
//CLASS USED IN PROGRAM
class carInsurance
{
private:
int total;
int customerNo;
string name;
string iCno;
char dob[10];
string nationality;
string address;
char phoneNo[15];
string email;
string occupation;
char carNo[10];
char expireDate[11];
float insuranceAmount;
char carUsage[30];
char manufacturingDate[11];
int package;
int option;
int additional;
int noCustomer[10];
public:
void add();
void presetdata();
static void deleteFunc(carInsurance noCustomer[]);
static void viewAll(carInsurance noCustomer[]);
//constructor name has to be the same as class
carInsurance(int carInsurance_total,
int carInsurance_customerNo,
string carInsurance_name,
string carInsurance_iCno,
char carInsurance_dob[10],
string carInsurance_nationality,
string carInsurance_address,
char carInsurance_phoneNo[15],
string carInsurance_email,
string carInsurance_occupation,
char carInsurance_carNo[10],
char carInsurance_expireDate[11],
float carInsurance_insuranceAmount,
char carInsurance_carUsage[30],
char carInsurance_manufacturingDate[11],
int carInsurance_package,
int carInsurance_option,
int carInsurance_additional)
{
total = carInsurance_total;
customerNo = carInsurance_customerNo;
name = carInsurance_name;
iCno = carInsurance_iCno;
dob[10] = carInsurance_dob[10];
nationality = carInsurance_nationality;
address = carInsurance_address;
phoneNo[15] = carInsurance_phoneNo[15];
email = carInsurance_email;
occupation = carInsurance_occupation;
carNo[10] = carInsurance_carNo[10];
expireDate[11] = carInsurance_expireDate[11];
insuranceAmount = carInsurance_insuranceAmount;
carUsage[30] = carInsurance_carUsage[30];
manufacturingDate[11] = carInsurance_manufacturingDate[11];
package = carInsurance_package;
option = carInsurance_option;
additional = carInsurance_additional;
} // end of constructor
carInsurance()
{ // Set all variables to null
total = 0;
customerNo = 0;
name = " ";
iCno = " ";
dob[10] = '\0';
nationality = " ";
address = " ";
phoneNo[15] = '\0';
email = " ";
occupation = " ";
carNo[10] = '\0';
expireDate[11] = '\0';
insuranceAmount = 0;
carUsage[30] = '\0';
manufacturingDate[11] = '\0';
package = 0;
option = 0;
additional = 0;
}
// SET
void setChar(char carInsurance_dob[10],
char carInsurance_phoneNo[15],
char carInsurance_carNo[10],
char carInsurance_expireDate[10],
char carInsurance_carUsage[30],
char carInsurance_manufacturingDate[10])
{dob[10] = carInsurance_dob[10];
phoneNo[15] = carInsurance_phoneNo[15];
carNo[10] = carInsurance_carNo[10];
expireDate[11] = carInsurance_expireDate[11];
carUsage[30] = carInsurance_carUsage[30];
manufacturingDate[11] = carInsurance_manufacturingDate[11];}
void setname(string carInsurance_name){name = carInsurance_name;}
void setiCno(string carInsurance_iCno){iCno = carInsurance_iCno;}
void setAddress(string carInsurance_address){address = carInsurance_address;}
void setString(string carInsurance_nationality, string carInsurance_email,string carInsurance_occupation)
{nationality = carInsurance_nationality; email = carInsurance_email; occupation = carInsurance_occupation;}
void setInt(int carInsurance_total, int carInsurance_customerNo, int carInsurance_package, int carInsurance_option, int carInsurance_additional)
{customerNo = carInsurance_customerNo; package = carInsurance_package; option = carInsurance_option; additional = carInsurance_additional;}
void setFloat (float carInsurance_insuranceAmount){insuranceAmount = carInsurance_insuranceAmount;}
// GET
string getname(){return name;}
string getiCno(){return iCno;}
string getaddress(){return address;}
string getString(){return nationality; return email; return occupation;}
int getInt(){return total; return customerNo; return package; return option; return additional;}
float getFloat(){return insuranceAmount;}
}; //end class
Here goes my main:
//function declaration
//to prevent overload run function outside
void add();
//THE MAIN FUNCTION OF PROGRAM
int main()
{
carInsurance obj; // obj is class object
carInsurance *noCustomer[10];
int choice;
while(choice != 4)
{
cout << "1. ADD, UPDATE, DELETE\n" << "2. SEARCH\n" << "3. VIEW ALL\n" << "4. SUMMARY REPORT\n" << "5. EXIT\n" << endl;
cout << "Enter your choice: ";
cin >> choice;
system("cls");
switch(choice)
{
case 1:
{
cout << "___________________________________\n";
cout << "\n\tADD/UPDATE/DELETE\n";
cout << "___________________________________\n";
cout << "\n1. ADD\n2. UPDATE\n3. DELETE\n" << endl;
cin >> choice;
system("cls");
switch(choice)
{
case 1:
{
int i;
int total = 0;
cout << "How many customer? ";
cin >> total;
for(i=0; i<total; ++i)
{
cout << "________________________________\n";
cout << "\n\tCUSTOMER NO. " << 1 + i;
cout << "\n________________________________\n";
noCustomer[i]->add(); // this is function call to input
}
break;
}
case 2:
{
int paymentID;
//cout << "UPDATE" << endl;
cout << "\nEnter the customer ID that you want to update:";
cin >> paymentID;
// function here
break;
}
case 3:
{
int paymentID;
//cout << "DELETE" << endl;
cout << "\nEnter the customer ID that you want to delete:";
cin >> paymentID;
noCustomer[10]->deleteFunc(noCustomer[10]);
break;
}
} // End of switch case for add,update,delete
system("cls");
break;
} // End of case 1
case 2:
{
cout << "___________________________\n";
cout << "\n\t SEARCH\n";
cout << "___________________________\n";
system("pause");
system("cls");
break;
}
case 3:
{ cout << "___________________________\n";
cout << "\n\tVIEW ALL\n";
cout << "___________________________\n";
obj.presetdata();
noCustomer[10]->viewAll(noCustomer[10]);
cout<<"\n";
system("pause");
system("cls");
break;
}
case 4:
{
cout << "___________________________\n";
cout << "\n\tSUMMARY REPORT\n";
cout << "___________________________\n\n";
cout << "1. Sorted by different month\n2. Sorted by different car type\n3. Sorted by different insurance" << endl;
cin >> choice;
switch(choice)
{
case 1:
{
break;
}
case 2:
{
break;
}
case 3:
{
break;
}
default:
cout << "Wrong input! Please choose again: ";
cin >> choice;
system("pause");
}
break;
}
case 5:{
cout << "___________________________\n";
cout << "\n\tTHANK YOU!\t\n";
cout << "___________________________";
exit(0); }
default:
continue;
}// End of switch case
}// End of while
return 0; //indicates success
}//End of main
I see a problem in the inner switch statement:
case 1:
{
int i;
int total = 0;
cout << "How many customer? ";
cin >> total;
for(i=0; i<total; ++i)
{
cout << "________________________________\n";
cout << "\n\tCUSTOMER NO. " << 1 + i;
cout << "\n________________________________\n";
noCustomer[i]->add(); // this is function call to input
break;
}
}
case 2:
The break operator breaks the loop, but does not prevent executing case 2: branch.
Yet another problem: re-assignment of choice. User may input 4 in any input request that will break while (choice != 4) unexpectedly. You can avoid troubles with break and re-assignments by using functions.
There is a lot of out of array bounds access by indexes that are equal to array sizes.
It is not clear what you want to reach in dob[10] = carInsurance_dob[10]; It copies 11th char. Maybe you want to copy the whole char array. Use std::string for error-free code.

c++ pushing array elements to the right

I am newbie into programming and have this c++ school quizzes.
I wanted to push entered arrays elements to the right.
here is my existing code
Blockquote
// automatac++.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <list>
#include <iterator>
#include <conio.h>
#include <cstring>
//using namespace std;
using std::cout;
using std::cin;
using std::endl;
void menu_sel();
void push_element();
//void rem_element();
int in;
char array[100];
int p_elements;
int main()
{
menu_sel();
return 0;
}
void push_element() {
int p_elements;
for (int e = 0; e < 10; e++) {
}
cout << "Enter number of elements:";
cin >> p_elements;
cout << "Enter only " << p_elements << " elements"<<endl;
for (int e = 0; e < p_elements; e++ ) {
cin >> array[e];
}
cout << "Pushed elements are :";
for (int e = 0; e < p_elements; ++e) {
cout << array[e]<<" ";
}
//getch();
menu_sel();
}
/*
void rem_element() {
char remove;
int arr_position;
cout << "You have selected Pop.\nRemove elements from arrays \n";
cout << "Enter data to remove";
cin >>remove;
for (int ie -) {
}
system("pause");
}
*/
void menu_sel() {
int input;
cout << "\n****Menu Selection Here****";
cout << "\n1. Push \n2. Pop \n3. Exit \n";
cout << "select options here :";
cin >> input;
switch (input) {
case 1:
cout << "You have selected Push Stack\n";
push_element();
break;
case 2:
//cout << "You have selected Pop Stack\n";
//rem_element();
break;
default:
cout << "You have selected Invalid Options";
break;
system("cls");
return;
}
}
and here is the output
the output shows pushing elements to the left
the output was 3 e r 4
I wanted to shows output like this "4 r e 3"
thanks and regards,
You can always read your array backwards for output if you want to show it that way.
for (int e = p_elements-1; e >= 0; --e) {
cout << array[e]<<" ";
}

C++ function in switch statement is not executing

I'm new to c++ and I'm trying to make a simple class roster program that accepts new students storing the student data in an array that then be sorted and display the contents of the array. However when running the program and entering the menu selection, two of the three functions do not work. Any help or guidance is much appreciated. My code is here.
#include <cstdio>
#include <cstdlib>
#include <iomanip>
#include <iostream>
using namespace std;
//Create Students class
class Students
{
public:
char sFirstName[256];
char sLastName[256];
int sStudentID;
double sGrade;
double sGPA;
double nCreditHours;
};
//functions
Students addStudent();
//void displayRoster();
//void sortRoster();
void showMenu();
void showWelcome();
//Welcome function
void showWelcome()
{
cout << "Welcome to my class roster program. \n"
<< "This program can be used to add students to the roster, \n"
<< "which can then be sorted by either name or I.D. number. \n"
<< endl;
}
//Menu function
void showMenu()
{
cout << " Student Roster: \n"
<< "MAIN MENU PLEASE SELECT AN OPTION" << endl;
cout << "1) Add student to roster: " << endl;
cout << "2) Display current roster: " << endl;
cout << "3) Sort roster: " << endl;
cout << "4) Exit program: " << endl;
//cout << "5) Display roster sorted by 'student I.D.': " << endl;
//cout << "6) Display roster sorted by 'Grade': " << endl;
//cout << "7) Display roster sorted by 'GPA': \n" << endl;
cout << " Make your selection: \n" << endl;
}
//Add student function
Students addStudent()
{
Students student;
cout << "Add student to roster. \n"
<< "Enter first name: " << endl;
cin >> student.sFirstName;
cout << "Enter last name: " << endl;
cin >> student.sLastName;
cout << "Enter student I.D.: " << endl;
cin >> student.sStudentID;
return student;
}
void displayStudent(Students student)
{
cout << "Student name: " << student.sFirstName << " "
<< student.sLastName << endl;
cout << "I.D. # " << student.sStudentID << endl;
}
void displayRoster()
{
Students student[256];
int nCount;
for (int index = 0; index < nCount; index++)
{
displayStudent(student[index]);
}
}
int getStudents(Students student[], int nMaxSize)
{
int index;
for (index = 0; index < nMaxSize; index++)
{
char uInput;
cout << "Enter another student to the roster? (Y/N): ";
cin >> uInput;
if (uInput != 'y' && uInput != 'Y')
{
break;
}
student[index] = addStudent();
}
return index;
}
void sortRoster()
{
Students student[256];
int nCount;
//bubble swap
int nSwaps = 1;
while (nSwaps != 0)
{
nSwaps = 0;
for (int n = 0; n < (nCount - 1); n++)
{
if (student[n].sStudentID > student[n+1].sStudentID)
{
Students temp = student[n+1];
student[n+1] = student[n];
student[n] = temp;
nSwaps++;
}
}
}
}
int main()
{
int selection; //menu selection variable
//constants for menu selection
const int ADD_STUDENT = 1,
DISPLAY_ROSTER = 2,
SORT_ROSTER = 3,
QUIT_PROGRAM = 4;
Students student[256];
//int nCount = getStudents(student, 256);
do
{
showWelcome(); //Show welcome message
showMenu(); //Show menu options
cin >> selection;
while (selection < ADD_STUDENT || selection > QUIT_PROGRAM)
{
cout << "Enter a valid selection: ";
cin >> selection;
}
if (selection != QUIT_PROGRAM)
{
switch (selection)
{
case ADD_STUDENT:
addStudent();
break;
case DISPLAY_ROSTER:
displayRoster();
break;
case SORT_ROSTER:
sortRoster();
break;
}
}
}
while (selection != QUIT_PROGRAM);
return 0;
}
The problem is not in the switch.
The addStudent() is not adding the student into any list or array. Also since it return type is Students you should add it into the any array of Students. Since you have not stored any data display won't display anything.
The another problem is of nCount. You are using it in for comparison without initializing it. Also to keep nCount synchronized either make it global, use as pointer or handle it with return.
Also the problem is in displayRoster(). You are declaring Students array as Students student[256]; and you are using it without initializing. Also if initialized, it won't have the data which was given as input.
NOTE: Sit and read your code again, there are many more mistakes. Try visualizing how your data should be stored and how your code is to behave and then start writing code.
Your nCount is not initialised. Since this variable is used in those two functions (and assuming that it refers to the total count), you can declare it as a global variable:
nCount=0;
Everytime you add a new entry, you can increment the counter as:
nCount++;
Another suggestion to make your code actually work:
student[i++]=addStudent();
where i is a counter initialised to 0. Your addStudent() function returns an object, and you discard it. Store it in the array of objects you created:
Students student[256];
Also, since you use the above in almost all functions, it is best to declare it as global rather than redeclaring in each function.

Open address hashtable segmentation fault

Iam trying to create an open addressed hash table. The user has to be able to define the table's size. For my collision resolution I am using psuedo random probing -
http://algoviz.org/OpenDSA/Books/OpenDSA/html/HashCImproved.html#HashingPseudoRandomProbePRO
Anyway the hashing function(s) seem to work fine until I only have 1 more space to fill in the table. As soon as I input the final element of the table my program crashes and I get a segmentation fault. I've been pulling my hair out trying to find the problem for hours. Please help!
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
using namespace std;
class HashTable
{
string* hash;
bool* inTable;
vector<int> perm;
int table_size;
int permFunc(int, int);
void permutation();
int hashFunc(string);
public:
//constructor for a hashtable
HashTable(int);
//deconstructor for hashtable
~HashTable();
bool isFull();
//The prototype for the insert method
void insert(string);
//The prototype for the lookup method
bool lookup(string);
//The prototype for the remove method
void remove(string);
//The prototype for the size method
int size();
//The prototype for the print method
void print();
};
//constructor
HashTable::HashTable(int table_size)
{
this -> table_size = table_size;
hash = new string[table_size];
inTable = new bool[table_size];
for(int i=0; i<table_size; i++) perm.push_back(i);
permutation();
}
//deconstructor
HashTable::~HashTable()
{
delete [] hash;
delete [] inTable;
}
//creates a permutation of the perm vectors index elements
void HashTable::permutation()
{
random_shuffle ( perm.begin() + 1, perm.end() );
}
//Hash function method for strings
int HashTable::hashFunc(string str)
{
int key = 0;
for (int i=0; i < str.size(); i++)
{
key += static_cast<int>(str.at(i));
}
cout << "key is:" << key << endl;
return key%table_size;
}
int HashTable::permFunc(int index, int i)
{
int temp = index;
index += perm[i];
if(index > table_size){index = index - table_size;}
if(inTable[index] == false ){return index;}
index = temp;
i++;
permFunc(index, i);
}
bool HashTable::isFull()
{
int num=0;
for(int i=0;i<table_size; i++)
{
if(inTable[i] == true){num ++;}
if(num == table_size){
cout<<"FULL TABLE";
return true;}
}
return false;
}
//Method that inserts an integer into the hash table
void HashTable::insert(string str)
{
int i=1;
if(isFull()){return;}
int pos = hashFunc(str);
if(inTable[pos] == true)
{
int permPos = permFunc(pos, i);
hash[permPos] = str;
inTable[permPos] = true;
}
else
hash[pos] = str;
inTable[pos] = true;
}
//A function that prints out the menu
void menu()
{
cout << endl;
cout << "press i to insert an element into the hash table" << endl;
cout << "press d to inTableete an element from the hash table" << endl;
cout << "press l to look up an element" << endl;
cout << "press s to obtain the size of the table" << endl;
cout << "press p to print the current table" << endl;
return;
}
//The main method
//Implements all the input and output
int main(void)
{
int table_size;
cout << "Enter table size: ";
cin >> table_size;
HashTable h(table_size);
while(true)
{
char c;
string str;
menu();
getline(cin, str);
stringstream stream;
stream << str;
stream >> c;
switch(c)
{
case 'i':
getline(cin, str);
h.insert(str);
break;
case 'd':
getline(cin, str);
h.remove(str);
break;
case 'l':
getline(cin, str);
cout << h.lookup(str) << "\n";
break;
case 's':
cout << h.size() << "\n";
break;
case 'p':
h.print();
break;
default:
cout << "Don't understand '" << c << "'\n";
}
}
return 0;
}
I don't know if this is your problem but this line:
if(index > table_size){index = index - table_size;}
will leave index at table_size which is out of bounds for your array. Change the > to >=
If this isn't it, could you add an example crashing input to your post, for testing?