Bubblesort giving access violation - c++

Hi everyone I am trying to finish a assignment for class where I need to sort a File full of employees by their ID number. There are 10 lines in the file each with an employees info. The order is ID LASTNAME FIRSTNAME
The program ran fine before I wrote the sort function and copied all the data properly into the array, but now after adding my sort function I keep getting a access violation with no hints as to what is causing it.
I would appreciate any help.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
class Employee
{
public:
int _id;
string _lastName;
string _firstName;
Employee()
{
_id = 0;
_lastName = "n/a";
_firstName = "n/a";
}
};
void copyFile10(Employee [], int);
void sortFile10(Employee [], int);
int main()
{
const int size10 = 10;
Employee employees10[size10];
copyFile10(employees10, size10); //1.fill array/copy file
sortFile10(employees10, size10); //2. sort
system("pause");
return 0;
}
void copyFile10(Employee employees10[], const int size)
{
ifstream data10("data_10.dat");
for(int count = 0; count < 10; count++) //1.fill array/copy file
{
data10 >> employees10[count]._id;
data10 >> employees10[count]._lastName;
data10 >> employees10[count]._firstName;
}
data10.close();
}
void sortFile10(Employee employees10[], const int size)
{
Employee buff1;
Employee buff2;
int counter = 0;
bool ordered = false;
while (ordered == false)
{
for(int count = 0; count < size-1; count++)
{
if(employees10[count]._id > employees10[count+1]._id)
{
buff1._id = employees10[count+1]._id;
buff1._lastName = employees10[count+1]._lastName;
buff1._firstName = employees10[count+1]._firstName;
buff2._id = employees10[count]._id;
buff2._lastName = employees10[count]._lastName;
buff2._firstName = employees10[count]._firstName;
employees10[count]._id = buff1._id;
employees10[count]._lastName = buff1._lastName;
employees10[count]._firstName = buff1._firstName;
employees10[count+1]._id = buff2._id;
employees10[count+1]._lastName = buff2._lastName;
employees10[count+1]._lastName = buff2._lastName;
counter++;
}
if(counter == 0)
ordered = true;
else
counter = 0;
}
}
}

for(int count = 0; count < size; count++)
{
if(employees10[count]._id > employees10[count+1]._id)
What happens here on the last iteration of the loop (i.e. when count is 9)?

Related

How to add/update/delete Department in university class? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 10 months ago.
Improve this question
#include <iostream>
using namespace std;
class Professor
{
string name;
long employeeID;
string designation;
public:
Professor()
{
name = "";
employeeID = 0;
designation = "";
}
Professor(string n, long ID, string d)
{
name = n;
employeeID = ID;
designation = d;
}
void setProfessorData(string name1, long ID1,string d1)
{
name = name1;
employeeID = ID1;
designation = d1;
}
string getName()
{
return name;
}
long getID()
{
return employeeID;
}
string getDesignation()
{
return designation;
}
};
class Department
{
private:
string name;
long deptID;
Professor profList[5];
int noOfprofessors;
public:
Department()
{
name = "";
deptID = 0;
for (int i = 0; i < 5; i++)
{
profList[i].setProfessorData ("",0,"");
}
noOfprofessors = 0;
}
Department(string name1, long id1, Professor array[5], int no_of_dpt)
{
name = name1;
deptID = id1;
for (int i = 0; i < 5; i++)
{
profList[i] = array[i];
}
noOfprofessors = no_of_dpt;
}
void setDepartmentData(string n, long i, Professor arr[5], int nd)
{
name = n;
deptID = i;
for (int i = 0; i < 5; i++)
{
profList[i] = arr[i];
}
noOfprofessors = nd;
}
string getName1()
{
return name;
}
long getDeptId()
{
return deptID;
}
int getnoOfProfessors()
{
return noOfprofessors;
}
};
class University
{
private:
string name;
Department dept[5];
int numberOfDepartments;
public:
University(string n, Department array[5], int no)
{
name = n;
for (int i = 0; i > 5; i++)
{
dept[i] = array[i];
}
numberOfDepartments = no;
}
void setUniversityData(string name1, Department arr[5], int n1)
{
name = name1;
for (int i = 0; i < 5; i++)
{
dept[i] = arr[i];
}
numberOfDepartments = n1;
}
bool addDepartment(Department D)
{
}
bool deleteDepartment(string name)
{
}
bool updateDepartment(int id, string name)
{
}
};
How to add, delete, and update Department in University class?
I have provided the skeleton code. I have implemented all constructors and destructors, but I don't know how to implement addDepartment(), deleteDepartment(), and updateDepartment()`. Kindly look into this and help me to complete this task.
First off, several of your for loops are incorrect, namely the ones in the following methods:
Department::Department(string, long, Professor[5], int), should be using no_of_dpt (or better, std::min(no_of_dpt, 5)) instead of 5 for the loop counter.
Department::setDepartmentData(), should be using nd (or better, std::min(nd, 5)) instead of 5 for the loop counter.
University::University(string, Department[5], int), should be using no (or better, std::min(no, 5)) instead of 5 for the loop counter. Also, the loop needs to use < instead of >.
University::setUniversityData(), should be using n1 (or better, std::min(n1, 5)) instead of 5 for the loop counter.
That being said, you already have basic logic for adding elements to arrays, so you can implement addDepartment() by applying that logic correctly, eg:
bool addDepartment(Department D)
{
if (numberOfDepartments < 5)
{
dept[numberOfDepartments] = D;
++numberOfDepartments;
}
}
And, you can easily implement deleteDepartment(), you just need to find the index of the desired Department and shift the remaining departments down 1 element in the array, eg:
bool deleteDepartment(string name)
{
for (int i = 0; i < numberOfDepartments; ++i)
{
if (dept[i].getName1() == name)
{
for(int j = i+1; j < numberOfDepartments; ++j)
{
dept[j-1] = dept[j];
}
--numberOfDepartments;
dept[numberOfDepartments].setDepartmentData("", 0, NULL, 0);
break;
}
}
}
Unfortunately, you cannot implement updateDepartment() with the current code you have shown. This is because University does not have access to update the Department::name field directly, and it does not have access to a Department's existing professor data in order to call Department::setDepartmentData() with just a new name.
So, you will have to fix this issue first, either by making University be a friend of Department, or by adding a Department::setName() setter, or by adding getters for the data in the Department::profList array.
However, once you have addressed that, you can then implement updateDepartment(), eg:
class Department
{
private:
string name;
...
friend class University;
public:
...
};
class University
{
private:
...
public:
...
bool updateDepartment(int id, string newName)
{
for (int i = 0; i < numberOfDepartments; ++i)
{
if (dept[i].getDeptId() == id)
{
dept[i].name = newName;
break;
}
}
}
};
Or:
class Department
{
private:
string name;
...
public:
...
void setName(string newName)
{
name = newName;
}
};
class University
{
private:
...
public:
...
bool updateDepartment(int id, string newName)
{
for (int i = 0; i < numberOfDepartments; ++i)
{
if (dept[i].getDeptId() == id)
{
dept[i].setName(newName);
break;
}
}
}
};
Or:
class Department
{
private:
...
Professor profList[5];
int noOfprofessors;
public:
...
Professor* getProfessors()
{
return profList;
}
int getnoOfProfessors()
{
return noOfprofessors;
}
};
class University
{
private:
...
public:
...
bool updateDepartment(int id, string newName)
{
for (int i = 0; i < numberOfDepartments; ++i)
{
if (dept[i].getDeptId() == id)
{
dept[i].setDepartmentData(newName, dept[i].getDeptId(), dept[i].getProfessors(), dept[i].getnoOfProfessors());
break;
}
}
}
};

How to send an array struct into a function using pointers

How to send an array of structs into a function as a parameter?
The employee variable is a struct.
My function:
void arraySort(struct Employee *employee[])
{
bool flag = false;
for (int i = 0; i < 5000; i++)
{
int empID1 = employee[i]->empID;
int empID2 = employee[i + 1]->empID;
flag = Employee().compareEmpID(empID1, empID2);
if (flag == true)
{
Employee swap;
swap = *employee[i + 1];
*employee[i] = *employee[i + 1];
*employee[i + 1] = swap;
}
}
}
Which calls this function:
bool Employee::compareEmpID(int empID1, int empID2)
{
if (empID1 >= empID2)
return true;
return false;
}
I am trying to invoke a call to the arraySorts function from main by using the employee array struct as a pointer:
arraySort(*employee);
The function compareEmpID have to be a static method in struct employee and invoked by calling as Employee::compareEmpID.
There are some issues in for your arraySort method.
You hard code the number 5000, that means your array need to have 5000 elements or more, otherwise you will get error about illegal memory access.
The variable swap should be a pointer and declared outside of the for loop.
Your swap logic is wrong.
I rewrite the program base on your code and tested it.
#include<iostream>
using namespace std;
struct Employee {
int empID;
static bool compareEmpID(int empID1, int empID2) {
return empID1 > empID2;
}
};
void arraySort(Employee *employees[], int size) {
bool flag = false;
Employee *swap;
for(int i=0; i<size-1; i++) {
int empID1 = employees[i]->empID;
int empID2 = employees[i+1]->empID;
flag = Employee::compareEmpID(empID1,empID2);
if(flag) {
swap = employees[i+1];
employees[i+1] = employees[i];
employees[i] = swap;
}
}
}
int main(int argc, char* args[]) {
Employee** employee;
employee = new Employee*[2];
employee[0] = new Employee;
employee[0]->empID = 5;
employee[1] = new Employee;
employee[1]->empID = 1;
arraySort(employee, 2);
cout << "emp[0]: " << employee[0]->empID << endl;
cout << "emp[1]: " << employee[1]->empID << endl;
delete employee[0];
delete employee[1];
delete[] employee;
return 0;
}
Hope this helps you boots your learning progress.

Why does my code have an "Apple Mach-O Linker Error?"

I get this error when i build the program: Apple Mach-O Linker (ld) Error Linker Command failed with exit code 1. Usually when I try to fix this error, its because the file with the main function is #include-ing a file more than once. However, I do not believe that that is the case this time. I am also notified by X Code that the duplicate symbol _passed in: ranker.o and olympic.o.
//competitor.h
#ifndef __Olympic_Lab__competitor__
#define __Olympic_Lab__competitor__
#include <iostream>
using namespace std;
class Competitor {
char* name = nullptr;
int laneAssignment;
float time;
public:
Competitor(char n[], int lane);
~Competitor();
void setTime(float f);
char* getName(){ return name; }
int getLane(){ return laneAssignment; }
float getTime(){ return time; }
void print(){ cout << name << endl; }
};
#endif
//competitor.cpp
#include "competitor.h"
Competitor::Competitor(char n[], int lane){
name = n;
laneAssignment = lane;
}
Competitor::~Competitor(){
//does nothing for now
}
void Competitor::setTime(float t){
time = t;
}
//ranker.h
#ifndef __Olym__ranker__
#define __Olym__ranker__
#include <vector>
#include "competitor.h"
using namespace std;
int passed = 0;
class Ranker {
bool boolean = true;
public:
vector<Competitor*> rv;
Ranker(int lanes);
~Ranker();
int addList(Competitor* c);
Competitor* getLane(int lane);
Competitor* getFinish(int finish);
int getFilled();
};
#endif
//ranker.cpp
#include "ranker.h"
Ranker::Ranker(int lan){
rv.resize(lan - 1);
for(int i = 0; i <= rv.size(); i++){
rv[i] = nullptr;
}
}
Ranker::~Ranker(){
for(int i = 0; i <= rv.size(); i++){
delete rv[i];
}
}
int Ranker::addList(Competitor *c){
if(c != NULL && passed <= 4){
rv[passed++] = c;
return passed - 1;
}
return 0;
}
Competitor* Ranker::getLane(int lane){
for(int i = 0; i <= rv.size(); i++){
if(rv[i]->getLane() == lane && rv[i] != NULL){
return rv[i];
}
}
return rv[0];
}
Competitor* Ranker::getFinish(int finish){
if(boolean){
Competitor *temp = nullptr;
int highestIndex;
for(int i = rv.size(); i >= 0; i--){
highestIndex = i;
for(int j = i; j >= 0; j--){
if(rv[j] != nullptr && rv[highestIndex] != nullptr){
if(rv[j]->getTime() > rv[highestIndex]->getTime())
highestIndex = j;
}
}
temp = rv[i];
rv[i] = rv[highestIndex];
rv[highestIndex] = temp;
}
delete temp;
temp = *new Competitor*;
boolean = false;
}
return rv[finish - 1];
}
int Ranker::getFilled(){
int filled = 0;
for(int i = 0; i <= rv.size(); i++){
if(rv[i] != NULL){
filled++;
}
}
return filled;
}
//olympic.h
#ifndef _Olympic_Lab__olympic__
#define _Olympic_Lab__olympic__
#include "ranker.h"
#endif
//olympic.cpp
#include "olympic.h"
int main(){
const int lanes = 4;
Ranker rank(lanes);
Competitor* starters[4];
starters[0] = new Competitor("EmmyLou Harris", 1);
starters[1] = new Competitor("Nanci Griffith", 2);
starters[2] = new Competitor("Bonnie Raitt", 3);
starters[3] = new Competitor("Joni Mitchell", 4);
starters[0]->setTime((float)12.0);
starters[1]->setTime((float)12.8);
starters[2]->setTime((float)11.0);
starters[3]->setTime((float)10.3);
for(int i = 0; i < lanes; i++){
rank.addList(starters[i]);
}
cout << "Competitors by lane are:" << endl;
for(int i = 1; i <= lanes; i++)
rank.getLane(i)->print();
cout << "Rankings by finish are:" << endl;
for(int i = 1; i <= lanes; i++)
rank.getFinish(i)->print();
for(int i = 0; i < lanes; i++){
delete starters[i];
}
}
It would be appreciated if someone could assist me in finding exactly what causes this error. Thanks!
If you declare a variable in a header it will be duplicated in every file that includes the header.
So int passed = 0; in ranker.h is going to give you a lot of grief. ranker and olympian both have allocated a different passed and the linker now has no clue which one is the real passed.
So what you probably want is
extern int passed;
in ranker.h to declare that passed will exist at some point, if it doesn't yet, so it doesn't need to be allocated. The compiler will happily carry on and allow you to use passed.
And then in ranker.cpp, declare
int passed = 0;
to allocate passed and satisfy the linker. Now you have only one passed and anyone who includes ranker.h can see and use it.
If you want more than one passed, you have to do something else so that they don't share the same name and scope, but this doesn't look like your goal.
Off topic: resist the urge to put using namespace std;in a header file. It can lead to future problems that can be very hard to debug. More here: Why is "using namespace std" considered bad practice?

Function removes too much

I'm doing a phone registry and in it you need to be able to add, remove and show the phones on stock. I've made it possible to add in phones but whenever I add let's say 3 phones and remove the second one then both the third and second phone are deleted and I don't understand why.
This is my CellPhoneHandler.h file:
#ifndef CELLPHONEHANDLER_H
#define CELLPHONEHANDLER_H
#include "CellPhone.h"
class CellPhoneHandler
{
private:
CellPhone **phone;
int nrOfPhones;
int priceOfPhone;
int stockCapacity;
int nrOfPhonesInArr;
public:
CellPhoneHandler();
~CellPhoneHandler();
void addPhone(string brand, int nrOf, int price);
bool removePhoneFromStock(string name, int nrOf);
int getNrOfPhones() const;
int getNrOfPhonesInArr() const;
int getPrice() const;
void getPhonesAsString(string arr[], int nrOf, int priceOfPhone) const;
};
#endif // !CELLPHONEHANDLER_H
this is my CellPhoneHandler.cpp file.
#include "CellPhoneHandler.h"
CellPhoneHandler::CellPhoneHandler()
{
this->phone = nullptr;
this->nrOfPhones = 0;
this->priceOfPhone = 0;
this->stockCapacity = 0;
this->nrOfPhonesInArr = 0;
}
CellPhoneHandler::~CellPhoneHandler()
{
for (int i = 0; i < nrOfPhonesInArr; i++)
{
delete phone[i];
}
delete[] phone;
}
void CellPhoneHandler::addPhone(string brand, int nrOf, int price)
{
if (stockCapacity < nrOfPhonesInArr + 1)
{
CellPhone ** tempArray = new CellPhone*[this->nrOfPhonesInArr + 1];
for (int i = 0; i < nrOfPhonesInArr; i++)
{
tempArray[i] = this->phone[i];
}
delete[] this->phone;
this->phone = tempArray;
this->phone[this->nrOfPhonesInArr] = new CellPhone(brand, nrOf, price);
this->nrOfPhonesInArr++;
//this->stockCapacity++;
}
}
bool CellPhoneHandler::removePhoneFromStock(string name, int nrOf)
{
bool phoneFound = false;
int index = nrOfPhonesInArr;
for (int i = 0; i < nrOfPhonesInArr; i++)
{
if (this->phone[i]->getBrand() == name);
{
index = i;
phoneFound = true;
this->nrOfPhonesInArr--;
}
}
if (phoneFound == true)
{
delete phone[index];
phone[index] = nullptr;
}
return phoneFound;
}
int CellPhoneHandler::getNrOfPhones() const
{
return this->nrOfPhones;
}
int CellPhoneHandler::getNrOfPhonesInArr() const
{
return this->nrOfPhonesInArr;
}
int CellPhoneHandler::getPrice() const
{
return this->priceOfPhone;
}
void CellPhoneHandler::getPhonesAsString(string arr[], int nrOf, int priceOfPhone) const
{
for (int i = 0; i < nrOf; i++)
{
arr[i] = this->phone[i]->toString();
}
}
The problem is caused by an unwanted ;.
if (this->phone[i]->getBrand() == name); // if ends here.
The next block is executed for all items.
{
index = i;
phoneFound = true;
this->nrOfPhonesInArr--;
}
Remove that ; in the if line.

Deleting a record from array of pointers of my own class type

I have created an Employee class:
class Employee {
private:
int idNumber;
string name, department, position;
public:
Employee() {
idNumber = 0;
name = department = position = "";
}
Employee(string n, int idn) {
name = n;
idNumber = idn;
department = position = "";
}
Employee(string n, int idn, string dep, string pos) {
name = n;
idNumber = idn;
department = dep;
position = pos;
}
void setName(string n) {
name = n;
}
void setidNumber(int idn) {
idNumber = idn;
}
void setDepartment(string dep) {
department = dep;
}
void setPosition(string pos) {
position = pos;
}
string getName() {
return name;
}
int getidNumber() {
return idNumber;
}
string getDepartment() {
return department;
}
string getPosition() {
return position;
}
};
Now, i created a 2D array of Pointers of type Employee:
int n=2;
Employee **p = new Employee * [n];
for (int i=0; i < n; i++)
p[i] = new Employee;
I stored two records successfully as under:
Name ID Number Department Position
FS 30 CS BS
AT 27 CS BS
I have this code to delete the record of Employees:
string del_name;
int flag = 0;
cin.ignore();
cout << "Enter name: ";
getline(cin, del_name);
for (int i=0; i < n; i++) {
while (del_name == p[i]->getName() && i < n) {
if (del_name == p[i]->getName()) {
delete p[i];
p[i] = NULL;
--k;
++flag;
cout << "Record deleted." << endl;
break;
}
else
{
flag = 0;
}
}
}
if (flag == 0)
cout << "No record found having name " << del_name << "." << endl;
Now, What's the problem:
If a record is found at multiple times. It deletes successfully even if all the records gets deleted.
But if ALL the records are unique and I delete the records one by one and all the records get deleted in this way then the program gets terminated.
Also, is there any other optimized approach to delete records without using VECTORS.
I hope i have clearly explained my problem. I can provide further details if needed.
Thank you for your time
First, usage of std::vector<> or some other container object is the way to go about this. If you can write code that beats (in terms of speed) written by professional library writers, then go ahead.
Second, what is your goal? If it's to simply deallocate entries in that array depending on some criteria, the loop you wrote is overly complex.
bool recordDeleted = false;
for (int i=0; i < n; ++i)
{
if (del_name == p[i]->getName())
{
delete p[i];
p[i] = NULL;
recordDeleted = true;
}
}
if ( !recordDeleted )
{
// record not found
}