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.
Related
In the class Element, i have a property called size with default value 0.
When I call the insertElement on main() the line that calls size++ works fine but, in the next line when function shiftElementsToRight(i); are called, the size element are restarted to 0.
Why this happens? I'm declaring in wrong way my Element class?
Using g++ 9.2.1 on Ubuntu Linux
#include<iostream>
using namespace std;
int const ARRAY_MAX = 100;
class Element {
public:
int elements[ARRAY_MAX] = {};
int size = 0;
void shiftElementsToRight(int pos) {
int temp = elements[pos+1];
for (int i=ARRAY_MAX-1; i>=pos; i--) {
elements[i+1] = elements[i];
}
elements[pos] = NULL;
}
void shiftElementsToLeft(int pos) {
int temp = elements[pos];
int i = ARRAY_MAX;
for (int i=pos; i<ARRAY_MAX-1; i++) {
elements[i-1] = elements[i];
}
}
void insertElement(int value) {
int i = 0;
size++;
while ((i<ARRAY_MAX) && (elements[i] != NULL)) {
if (elements[i]>value) {
break;
}
i++;
}
shiftElementsToRight(i);
elements[i] = value;
}
int deleteElement(int value) {
int pos = binarySearch(value);
if (pos!=-1) {
shiftElementsToLeft(pos+1);
}
size--;
return pos;
}
int binarySearch(int value) {
int left = 0;
int right = size;
cout << "Begin" << endl;
while (left<right) {
int middle = left + (right -left) / 2;
cout << "L: " << left << " R: " << right << endl;
if (elements[middle] == value) {
return middle;
}
if (elements[middle]>value) {
right = middle-1;
}
if (elements[middle]<value) {
left = middle+1;
}
}
return -1;
}
};
int main() {
Element *element = new Element();
element->insertElement(3);
element->insertElement(2);
element->insertElement(5);
element->insertElement(6);
element->insertElement(4);
element->deleteElement(3);
return 0;
}
In
for (int i=ARRAY_MAX-1; i>=pos; i--) {
elements[i+1] = elements[i];
}
Your first access to elements is at position ARRAY_MAX - 1 + 1. You're accessing elements[ARRAY_MAX], which is outside the bounds of this array and (likely) points to size.
I'm trying to concatenate two arrays and at the end concatenate int, for example: result = arg + arg + 2;
I'm getting "read access violation" at + operator overloading.
I wrote the error and warning in comments below.
My code:
Main:
#include <iostream>
#include <string>
#include "CTable.h"
int main() {
CTable c_tab1, c_tab0;
c_tab0.SetNewSize(3);
c_tab1.SetNewSize(2);
c_tab0.SetValueAt(0, 22);
c_tab0.SetValueAt(1, 23);
c_tab0.SetValueAt(2, 24);
c_tab0.Print();
c_tab1.SetValueAt(0, 31);
c_tab1.SetValueAt(1, 32);
c_tab1.Print();
CTable c_tab3 = (c_tab0 + c_tab1 + 111);
c_tab3.Print();
return 0;
}
Class CTable:
#include <iostream>
#include <string>
using namespace std;
class CTable {
public:
CTable();
CTable(string sName, int iTableLen);
CTable(const CTable& pcOther);
CTable* pcClone();
~CTable();
void ShowName();
void ShowSize();
void SetName(string sName);
bool SetNewSize(int iTableLen);
void SetValueAt(int iOffset, int iNewVal);
void Print();
CTable& operator+(const CTable& pcNewTable);
CTable operator+(int iNewVal) const;
CTable& operator=(const CTable& pcNewVal) {
if (this != &pcNewVal) {
for (int i = 0; i < i_size; i++) {
this->piTable[i] = pcNewVal.piTable[i];
}
}
return *this;
}
private:
string s_name;
int i_size;
int* piTable;
const int SIZE = 10;
const string NAME = "Name";
};
#include <iostream>
#include <string>
#include "CTable.h"
#include <algorithm>
using namespace std;
CTable::CTable() {
s_name = NAME;
cout << "bezp: " << s_name << endl;
piTable = new int[SIZE];
i_size = SIZE;
}
CTable::CTable(string sName, int iTableLen) {
s_name = sName;
cout << "parametr: " << sName << endl;
piTable = new int[iTableLen];
i_size = iTableLen;
}
CTable::CTable(const CTable& pcOther) {
s_name = pcOther.s_name + "copied";
piTable = new int[pcOther.i_size];
i_size = pcOther.i_size;
for (int i = 0; i < pcOther.i_size; i++) {
piTable[i] = pcOther.piTable[i];
}
}
CTable::~CTable() {
delete[] piTable;
}
void CTable::SetName(string sName) {
s_name = sName;
}
bool CTable::SetNewSize(int iTableLen) {
if (iTableLen <= 0) {
cout << "Length has to be greater than 0" << endl;
return false;
}
int* pi_newTable = new int[iTableLen];
for (int i = 0; i < iTableLen; i++) {
pi_newTable[i] = piTable[i];
}
delete this->piTable;
this->i_size = iTableLen;
this->piTable = pi_newTable;
return true;
}
CTable* CTable::pcClone() {
CTable* ct = new CTable(s_name, i_size);
return ct;
}
void CTable::ShowName() {
cout << "Name: " << s_name << endl;
}
void CTable::ShowSize() {
cout << "Size: " << i_size << endl;
}
void CTable::SetValueAt(int iOffset, int iNewVal) {
if (iOffset >= this->i_size) {
return;
}
piTable[iOffset] = iNewVal;
}
void CTable::Print() {
for (int i = 0; i < i_size; i++) {
cout << piTable[i] << " ";
}
cout << endl;
}
CTable& CTable::operator+(const CTable& pcNewTable) {
CTable result("new_int", this->i_size);
result.i_size = (i_size + pcNewTable.i_size);
result.piTable = new int[i_size + pcNewTable.i_size];
for (int i = 0; i < i_size; i++) {
result.piTable[i] = piTable[i];
}
for (int i = 0; i < (pcNewTable.i_size); i++) {
result.piTable[i+i_size] = pcNewTable.piTable[i];
}
return result; //Warning C4172 returning address of local variable or temporary: result
}
CTable CTable::operator+(int iNewVal) const {
CTable result("new_int", this->i_size);
result.i_size = (i_size + 1);
result.piTable = new int[i_size + 1];
for (int i = 0; i < i_size; i++) {
result.piTable[i] = piTable[i]; //Exception thrown: read access violation. **this->piTable** was 0x1110122.
}
result.piTable[i_size + 1] = iNewVal;
return result;
}
What should I correct? I'm not sure about assigment operator overload, is it okay?
The member function SetNewSize has undefined behavior. In this loop
int* pi_newTable = new int[iTableLen];
for (int i = 0; i < iTableLen; i++) {
pi_newTable[i] = piTable[i];
}
it 1) uses uninitialized values because the array was not initialized and 2) iTableLen can be gretaer than the current value of i_size. You should at least zero initialize the array in constructors.
The copy assignment operator aslo has undefined behabior because the number of elements of the array of the object pcNewVal can be less than the number of elements of the array in the assigned object.
The first overloaded operator + also have undefined behavior. For starters as the warning says the operator returns reference to the local object result that will not be alive after exiting the operator. Secondly, there is a memory leak necause the array of the object is allocated anew and the previuous allocated memory in the constructor is not freed.
CTable result("new_int", this->i_size);
result.i_size = (i_size + pcNewTable.i_size);
result.piTable = new int[i_size + pcNewTable.i_size];
//...
The second overloaded operator + also has undefined behavior. As in the previous operator there is a memory leak.
In this statement
result.piTable[i_size + 1] = iNewVal;
there is an access memory outside the allocated array. There should be
result.piTable[i_size] = iNewVal;
It's crashing at the very end of the main() function where it needs to delete the starters objects. The error message that pops up when I run the program says: Debug assertion failed! Expression: _BLOCK_IS_VALID(pHead->nBlockUse). How do i fix it from crashing when deleting the starters objects?
#include <iostream>
#include <fstream>
#include "olympic.h"
using namespace std;
ofstream csis;
int main() {
const int lanes = 4;
Ranker rank(lanes);
csis.open("csis.txt");
// First make a list of names and lane assignments.
Competitor* starters[lanes];
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);
// The race is run; now assign a time to each person.
starters[0]->setTime((float)12.0);
starters[1]->setTime((float)12.8);
starters[2]->setTime((float)11.0);
starters[3]->setTime((float)10.3);
// Put everyone into the ranker.
for (int i = 0; i < lanes; i++)
rank.addList(starters[i]);
// Now print out the list to make sure its right.
cout << "Competitors by lane are:" << endl;
csis << "Competitors by lane are:" << endl;
for (int i = 1; i <= lanes; i++)
rank.getLane(i)->print();
// Finally, show how they finished.
cout << "Rankings by finish are:" << endl;
csis << "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];
csis.close();
}
ranker.cpp:
#include "ranker.h"
#include "competitor.h"
#include <stdlib.h>
Ranker::Ranker(int lanes) {
athlete = new Competitor*[lanes];
numAthletes = 0;
maxAthletes = lanes;
}
int Ranker::addList(Competitor* starter) {
if (numAthletes < maxAthletes && starter != NULL) {
athlete[numAthletes] = starter;
numAthletes++;
return numAthletes;
}
else
return 0;
}
Competitor* Ranker::getLane(int lane) {
for (int i = 0; i < numAthletes; i++) {
if (athlete[i]->getLane() == lane) {
return athlete[i];
}
}
return NULL;
}
Competitor* Ranker::getFinish(int position) {
switch(position) {
case 1:
return athlete[3];
break;
case 2:
return athlete[2];
break;
case 3:
return athlete[1];
break;
case 4:
return athlete[0];
break;
}
return NULL;
}
int Ranker::getFilled() {
return numAthletes;
}
Ranker::~Ranker() {
delete [] athlete;
}
competitor.h:
#ifndef _COMPETITOR_H
#define _COMPETITOR_H
class Competitor {
private:
char* name;
int lane;
double time;
public:
Competitor(char* inputName, int inputLane);
Competitor();
void setTime(double inputTime);
char* getName();
int Competitor::getLane();
double getTime();
void print();
~Competitor();
};
#endif
competitor.cpp:
#include "competitor.h"
#include <string>
#include <iostream>
#include <iomanip>
using namespace std;
Competitor::Competitor(char* inputName, int inputLane) {
name = inputName;
lane = inputLane;
}
Competitor::Competitor() {
name = 0;
lane = 0;
time = 0;
}
void Competitor::setTime(double inputTime) {
time = inputTime;
}
char* Competitor::getName() {
return name;
}
int Competitor::getLane() {
return lane;
}
double Competitor::getTime() {
return time;
}
void Competitor::print() {
cout << setw(20) << name << setw(20) << lane << setw(20) << setprecision(4) << time << endl;
}
Competitor::~Competitor() {
delete [] name;
}
Call stack:
before crash: http://i.imgur.com/d4sKbKV.png
after crash: http://i.imgur.com/C5cXth9.png
After you've added Competitor class, it seems the problem is that you delete its name in Competitor's destructor. But you assign it from string literal which can't really be deleted. I'm sure the stack trace leading to assertion will prove that.
One way of solving the problem would be using std::string to store the name.
Problem is when deleting the char* value on destructor, which is assigned with const char instead new char. So i have slightly changed the constructor to copy the const char to new char.
Competitor::Competitor(char* inputName, int charlen, int inputLane)
{
name = new char[charlen + 1];
memcpy(name , inputName, charlen );
name [charlen] = '\0';
lane = inputLane;
}
#include <iostream>
class MyClass
{
public:
MyClass() {
itsAge = 1;
itsWeight = 5;
}
~MyClass() {}
int GetAge() const { return itsAge; }
int GetWeight() const { return itsWeight; }
void SetAge(int age) { itsAge = age; }
private:
int itsAge;
int itsWeight;
};
int main()
{
MyClass * myObject[50]; // define array of objects...define the type as the object
int i;
MyClass * objectPointer;
for (i = 0; i < 50; i++)
{
objectPointer = new MyClass;
objectPointer->SetAge(2*i + 1);
myObject[i] = objectPointer;
}
for (i = 0; i < 50; i++)
std::cout << "#" << i + 1 << ": " << myObject[i]->GetAge() << std::endl;
for (i = 0; i < 50; i++)
{
delete myObject[i];
myObject[i] = NULL;
}
I am wondering why the objectPointer must be inside the for loop, if I take it out and place it right before the for loop, I get nonsensical results. Help would be appreciated, thanks...sorry for the terrible formatting.
myObject[i] = objectPointer;
It should be inside the loop because you are storing a new reference in the array of the pointers. If it is outside the loop, then all the array of pointers point to the same reference. In such scenario, you should be careful while deallocation as all the array of pointers point to the same memory location.
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)?