cannot swap objects in an array in C++ - c++

i am new to C++ and stuck in the swap stuff
the code below is a program of sort employee names in alphbetical order and print out the orginal one and sorted one ,but the
swap method doesn't work
the two output of printEmployees is excatly the same, can anyone help me? thx
#include <iostream>
#include <string>
#include <iomanip>
#include <algorithm>
using namespace std;
class employee
{
/* Employee class to contain employee data
*/
private:
string surname;
double hourlyRate;
int empNumber;
public:
employee() {
hourlyRate = -1;
empNumber = -1;
surname = "";
}
employee(const employee &other) :
surname(other.surname),
hourlyRate(other.hourlyRate),
empNumber(other.empNumber){}
void setEmployee(const string &name, double rate,int num);
string getSurname() const;
void printEmployee() const;
employee& operator = (const employee &other)
{employee temp(other);
return *this;}};
void employee::setEmployee(const string &name, double rate, int num) {
surname = name;
hourlyRate = rate;
empNumber = num;
}
string employee::getSurname() const { return surname; }
void employee::printEmployee() const {
cout << fixed;
cout << setw(20) << surname << setw(4) << empNumber << " " << hourlyRate << "\n";
}
void printEmployees(employee employees[], int number)
{
int i;
for (i=0; i<number; i++) { employees[i].printEmployee(); }
cout << "\n";
}
void swap(employee employees[], int a, int b)
{
employee temp(employees[a]);
employees[a] = employees[b];
employees[b] = temp;
}
void sortEmployees(employee employees[], int number)
{
/* use selection sort to order employees,
in employee
name order
*/
int inner, outer, max;
for (outer=number-1; outer>0; outer--)
{
// run though array number of times
max = 0;
for (inner=1;
inner<=outer; inner++)
{
// find alphabeticaly largest surname in section of array
if (employees
[inner].getSurname() < employees[max].getSurname())
max = inner;
}
if (max != outer)
{
//
swap largest with last element looked at in array
swap(employees, max, outer);
}
}
}
int main()
{
employee employees[5];
employees[0].setEmployee("Stone", 35.75, 053);
employees[1].setEmployee
("Rubble", 12, 163);
employees[2].setEmployee("Flintstone", 15.75, 97);
employees[3].setEmployee("Pebble", 10.25, 104);
employees[4].setEmployee("Rockwall", 22.75, 15);
printEmployees(employees, 5);
sortEmployees(employees,5);
printEmployees(employees, 5);
return 0;
}

This code is broken:
employee& operator = (const employee &other)
{employee temp(other);
return *this;}
It should be something like:
employee& operator= (const employee &other)
{
surname = other.surname;
hourlyRate = other.hourlyRate;
empNumber = other.empNumber;
return *this;
}

As told by others, fixing your assignment operator will solve the problem.
I see that you tried to implement operator= in terms of copy constructor but missed to do a swap. You can try the below approach if you want to avoid code duplication in your copy constructor and assignment operator.
employee& operator=(const employee& other)
{
employee temp(other);
swap(temp);
return *this;
}
void swap(employee& other)
{
std::swap(surname, other.surname);
std::swap(hourlyRate, other.hourlyRate);
std::swap(empNumber, other.empNumber);
}

Related

How to initialize an array of user-defined objects with a static ID counter?

Here is my code
#include <iostream>
#include <string>
class Person {
private:
int pancakesEaten, personID;
public:
Person() {
pancakesEaten = 0;
personID = setID();
}
static int setID() {
static int currID;
return currID++; // Returns currID and then increments.
}
bool operator>=(const Person& p);
bool operator<=(const Person& p);
void askPancakesEaten();
void print();
};
bool Person::operator>=(const Person& p) {
if(this->pancakesEaten >= p.pancakesEaten) {
return true;
}
return false;
}
bool Person::operator<=(const Person& p) {
if(this->pancakesEaten <= p.pancakesEaten) {
return true;
}
return false;
}
void Person::askPancakesEaten() {
std::cout << "Please enter how many pancakes you ate: ";
std::cin >> this->pancakesEaten;
}
void Person::print() {
std::cout << this->personID;
std::cout << "Person " << this->personID << " ate " << this->pancakesEaten << " pancakes";
}
int main() {
Person people[10];
for(int i = 0; i<10; i++) {
Person currPerson;
currPerson.askPancakesEaten();
currPerson.print();
}
}
My problem is that I am trying to initialize an array for 10 Person objects, and because of my static method, it is making my static count start at 10 when I enter my for loop.
I know I could get around this easily by just changing my constructor and getting rid of setID and just using i instead, but I am curious if there is another way around it?
... but I am curious if there is another way around it.
Why are you initializing an array and don't use it in the loop then?
for(int i = 0; i<10; i++) {
people[i].askPancakesEaten();
people[i].print();
}
Besides that setID() is named a bit unfortunate confusing (getNextID() might be a better, clearer choice IMO), there's nothing wrong with that implementation as you have it.
Also it would be better to make this function private, since how those ID's are kept and managed to be unique for the class instances, is an implementation detail, which should't be publicly accessible.

Sorting a vector with pointer at object C++

If anyone can help I would be very grateful.
How do i sort this vector:
vector<Person*>person
by this criterium:
Surname
I have already tried it using set but it removes object if there is more than 2 objects with same Surname
there are lot of string variables, and I need to sort it by
Surname
and then if surnames are the same, then I need to sort them by
Name
and also it sorts by hexadecimal value of that pointer...
EDIT:
More code as you ask:
for (pChild = pRoot->FirstChildElement("Member"); pChild != NULL; pChild = pChild->NextSiblingElement())
{
string Surname = pChild->Attribute("surname");
string Name = pChild->Attribute("name");
string DateOfBirth = pChild->Attribute("dateofbirth");
person.push_back(new Person(Surname, Name, DateOfBirth));
}
Without you showing more of your code, it is hard to help you, but I would look at the documentation for std::sort() as you can create custom operators to sort your vector.
Here's a complete example
#include <vector>
#include <iostream>
#include <algorithm>
class Person
{
public:
std::string s1, s2, s3;
Person(std::string S1, std::string S2, std::string S3) : s1(S1), s2(S2), s3(S3) {}
};
struct less_than_key
{
inline bool operator() (const Person* const p1, const Person* const p2)
{
if (p1->s1 < p2->s1)
return true;
else if (p1->s1 == p2->s1 && p1->s2 < p2->s2)
return true;
return false;
}
};
int main()
{
std::vector<Person*> persons{ new Person("C", "D", "E"), new Person("C", "C", "D"),
new Person("B", "C", "D"), new Person("B", "C", "E")};
std::sort(persons.begin(), persons.end(), less_than_key());
for (auto person : persons)
{
std::cout << person->s1 << ' ' << person->s2 << std::endl;
}
return 0;
}
I had a bit of fun doing it with std::set. There are a couple of examples of comparators. One function and one "functor."
#include <iostream>
#include <set>
#include <string>
struct Person {
uint64_t id;
std::string name;
std::string family_name;
bool operator<(const Person &other) const {
if (family_name == other.family_name) {
if (name == other.name) {
return id < other.id;
} else {
return name < other.name;
}
} else {
return family_name < other.family_name;
}
}
};
std::ostream &operator<<(std::ostream &os, const Person &x) {
return os << '{' << x.id << ", " << x.name << ", " << x.family_name << '}';
}
bool person_ptr_less(const Person *a, const Person *b) { return *a < *b; }
class PersonPtrComparator {
public:
bool operator()(const Person *a, const Person *b) const { return *a < *b; }
};
int main() {
std::set<Person *, bool (*)(const Person *, const Person *)> people(
person_ptr_less);
people.emplace(new Person{1, "Joe", "Smith"});
people.emplace(new Person{2, "Joe", "Blow"});
people.emplace(new Person{3, "Joa", "Smith"});
people.emplace(new Person{4, "Joe", "Smith"});
std::set<Person *, PersonPtrComparator> people_2(people.begin(),
people.end());
for (const auto &x : people) {
std::cout << *x << '\n';
}
std::cout << "---\n";
for (const auto &x : people_2) {
std::cout << *x << '\n';
}
return 0;
}
You can use a comparator like this:
// Simple class
class Person {
public:
string name;
Person(string name) {
this->name = name;
}
};
// create a comparator like this with two objects as parameters.
bool comparator(Person* a, Person *b) {
return a->name > b->name;
}
int main() {
vector<Person* > v;
v.push_back(new Person("ajay"));
v.push_back(new Person("tanya"));
// pass the comparator created into sort function.
sort(v.begin(), v.end(),comparator);
// printing output to check
for(int i=0;i<v.size();i++) {
cout<<v[i]->name<<endl;
}
}

Increase count of item for a customer

Hello I do a shopping list. I have a class Customer and a class Item. My program work like this, I ask the name of the customer if the customer isn't in the database I add this customer, and if the customer is I print an error in order to say that the customer exists. After that I print a list of 10 products, and ask the customer to choose a product and increase the count of the specific Item for this customer.
My program don't give any error, I try do debug but I don't find the error, because the program doesn't increase the count of anything.
This is my function in my main:
void DisplayList(Item shopList[10], Customer& custom)
{
int choose_item = 1;
while (choose_item != 0)
{
cout << "The items you can buy are: (0 to exit)" << endl;
for (int i = 0; i < 10; i++)
{
cout << i + 1 << ". " << shopList[i].getName() << " " << shopList[i].getUnitPrice() << " x" << shopList[i].getCount() << endl;
}
cout << "What item you would like to buy, Input: ";
cin >> choose_item;
custom.addItem(shopList[choose_item - 1]);
}
}
My customer header:
class Customer
{
public:
Customer(string);
Customer(){}
void addItem(Item);
set<Item> getItems() const;
private:
string _name;
set<Item> _items;
};
My customer cpp
Customer::Customer(string name)
{
_name = name;
}
Customer::Customer(){ };
void Customer::addItem(Item SpecificItem)
{
set<Item>::iterator it;
if ((it = _items.find(SpecificItem)) != _items.end())
{
SpecificItem.setCount(SpecificItem.getCount() + 1);
}
else
{
_items.insert(SpecificItem);
}
}
set<Item> Customer::getItems() const
{
return _items;
}
My item header:
class Item
{
public:
Item(string, string, double);
~Item();
//get and set functions
string getName() const;
string getSerialNumber() const;
int getCount();
double getUnitPrice() const;
void setCount(int count);
private:
string _name;
string _serialNumber; //consists of 5 numbers
int _count; //default is 1, can never be less than 1!
double _unitPrice; //always bigger than 0!
};
My item cpp
#include "Item.h"
Item::Item(string name, string serial_number, double price) : _name(name), _serialNumber(serial_number), _unitPrice(price), _count(1)
{
};
Item::~Item(){};
string Item::getName() const
{
return _name;
}
string Item::getSerialNumber() const
{
return _serialNumber;
}
int Item::getCount()
{
return _count;
}
double Item::getUnitPrice() const
{
return _unitPrice;
}
void Item::setCount(int count)
{
_count = count;
}

C++: Class Issues

I'm attempting to make my class do the following...
EmployeeHandler: Initializes m_employeeCount to zero.
AddEmployee: Invoked by menu option 1. Displays "NEW EMPLOYEE". Prompts the user for
the employee’s first name, last name, and pay rate, one at a time. Uses Employee.Setup to add
an employee to m_lstEmployee. Displays "Employee m_employeeCount added". Increments
m_employeeCount.
EmployeeSelection: Displays the list of employees, by index; prompts the user for an employee
index and returns the index.
EditEmployee: Invoked by menu option 2. Uses EmployeeSelection to get the index of the
employee to edit. Verifies if the index is valid and displays an error message if it is not. Uses
Employee.Output to display the selected employee’s current information. Prompts the user for
the employee’s new first name, last name, and pay rate, one at a time. Uses Employee.Setup to
change the employee’s information in m_lstEmployee. Displays “** Employee index updated”,
where index is the user selected index.
LayoffEmployee: Invoked by menu option 3. Uses EmployeeSelection to get the index of the
employee to lay-off. Uses Employee.Output to display the selected employee’s first name, last
name, and pay rate. Uses Employee.LayOff to lay the employee off. Displays "Employee
index laid off", where index is laid off employee’s index.
DisplayEmployeeList: Invoked by menu option 4. Displays "EMPLOYEES". Then uses
Employee.Output to display every employee record something like this, "[1] David Johnson,
PAY: $5.00 (CURRENT EMPLOYEE)" and a former employee record something like this, "[2]
David Johnson, PAY: $5.00 (FORMER EMPLOYEE)", where the number in the brackets is the
employee’s index in m_lstEmployee.
GetEmployee: Returns the address of the selected employee record in m_lstEmployee.
GetEmployeeCount: Returns the number of employees in m_employeeCount.
So far I have...
#ifndef _EMPLOYEEHANDLER
#define _EMPLOYEEHANDLER
#include "Employee.h"
class EmployeeHandler
{
public:
EmployeeHandler()
{
m_employeeCount = 0; //undefined?
};
void AddEmployee()
{
string firstName;
string lastName;
float payRate;
cout<<"NEW EMPLOYEE"<<endl;
cout<<"First Name:"<<endl;
cin>>firstName;
cout<<"Last Name:"<<endl;
cin>>lastName;
cout<<"Pay Rate:"<<endl;
cin>>payRate;
Employee.Setup(firstName,lastName,payRate); //Problem here
cout<<"**Employee m_employeeCount added"<<endl;
m_employeeCount+=1; //m_employeeCount undefined?
}
void EditEmployee()
{
int indexEdit;
string newFirst;
string newLast;
float newPay;
cout<<"Which employee would you like to edit"<<endl;
cin>>indexEdit;
EmployeeSelection(indexEdit); //undefined?
Employee.Output(); //
cout<<"Employee new first name:"<<endl;
cin>>newFirst;
cout<<"Employee new last name:"<<endl;
cin>>newLast;
cout<<"Employee new pay rate:"<<endl;
cin>>newPay;
Employee.Setup(newFirst,newLast,newPay); ///
cout<<"** Employee index updated"<<endl;
}
void LayoffEmployee()
{
EmployeeSelection();
Employee.Output(EmployeeSelection); //Problems here
Employee.LayOff(EmployeeSelection);
cout<<"Employee laid off"<<endl;
}
void DisplayEmployeeList()
{
cout<<"EMPLOYEES"<<endl;
for (int i=0; i<50; i++)
cout<<[i]<<Employee.Output(m_1stEmployee)<<endl; //
}
int EmployeeSelection()
{
int indexNumber;
for (int i= 0; i <50; i++)
cout<<[i]m_1stEmployee<<endl; //
cout<<"Which Employee Index would you like to select?"<<endl;
cin>>indexNumber;
for (int i = 0; i <50; i++)
if ([i]=indexNumber) //
return [i]
}
Employee& GetEmployee( int index )
{if (index=; // completely confused here
}
int GetEmployeeCount()
{
return m_employeeCount;
};
private:
Employee m_lstEmployee[50];
int m_employeeCount;
};
#endif
The employee.h file is as follows...
#ifndef _EMPLOYEE
#define _EMPLOYEE
#include<iostream>
#include<iomanip>
#include <string>
using namespace std;
class Employee
{
public:
void Setup( const string& first, const string& last, float pay );
{
m_firstName = first;
m_lastName = last;
m_payPerHour = pay;
m_activeEmployee = true;
}
string GetName()
{
return m_firstName+""+m_lastName
};
bool GetIsActive()
{
return m_activeEmployee;
};
void LayOff()
{
m_activeEmployee= false;
};
void Output()
cout<<GetName()<<",PAY:$"<<fixed<<setprecision(2)<<m_payPerHour<<endl;
private:
string m_firstName;
string m_lastName;
float m_payPerHour;
bool m_activeEmployee;
};
#endif
I've been stuck writing this class for the last two days trying to figure out what I'm doing wrong. This is the first time I've attempted to write classes in C++. Any and all help is much, much appreciated. I have marked places where I'm having problems with //.
Your code has many, many problems...
I'll start by providing compilable code that more or less does what you want. I'm not sure how you can go about asking questions, but compare it to your own code and read a good c++ book...
I've replaced your array with a vector. I've used a constructor to initialize Employee. I've (to my own dismay) added std, mainly because Employee shall live in its own header and it's not good to use a namespace in a header.
In c++ the operator[] is postfix (after the indexed expression).
Also, under normal circumstances I'll try and keep interface and implementation seperate where possible. At the least I would not use inline functions if not absolutely necessary.
The new code...:
#include <iostream>
#include <iomanip>
#include <vector>
#include <iterator>
#include <string>
class Employee
{
public:
//This is a constructor....
Employee( const std::string& first, const std::string& last, float pay )
//The members can be initialized in a constructor initializer list as below.
: m_firstName( first ), m_lastName( last ), m_payPerHour( pay ),
m_activeEmployee() //Scalars are initialized to zero - bool to false...
{
}
std::string GetName() const
{
return m_firstName+" "+m_lastName;
}
bool GetIsActive() const
{
return m_activeEmployee;
};
void LayOff()
{
m_activeEmployee = false;
}
std::ostream& Output( std::ostream& out ) const
{
return out << GetName() <<",PAY:$"
<< std::fixed << std::setprecision(2) << m_payPerHour;
}
private:
std::string m_firstName;
std::string m_lastName;
float m_payPerHour;
bool m_activeEmployee;
};
inline std::ostream& operator << ( std::ostream& os, const Employee& employee )
{
return( employee.Output( os ) );
}
class EmployeeHandler
{
public:
void AddEmployee()
{
std::string firstName;
std::string lastName;
float payRate;
std::cout<<"NEW EMPLOYEE"<<std::endl;
std::cout<<"First Name:"<<std::endl;
std::cin>>firstName;
std::cout<<"Last Name:"<<std::endl;
std::cin>>lastName;
std::cout<<"Pay Rate:"<<std::endl;
std::cin>>payRate;
employees_.push_back( Employee( firstName,lastName,payRate ) );
std::cout<<"**Employee m_employeeCount added"<<std::endl;
}
void EditEmployee()
{
std::string newFirst;
std::string newLast;
float newPay;
std::cout<<"Which employee would you like to edit"<<std::endl;
int indexEdit = GetSelection();
Employee& employee = employees_[indexEdit];
std::cout << employee << std::endl;
std::cout<<"Employee new first name:"<<std::endl;
std::cin>>newFirst;
std::cout<<"Employee new last name:"<<std::endl;
std::cin>>newLast;
std::cout<<"Employee new pay rate:"<<std::endl;
std::cin>>newPay;
employee = Employee( newFirst, newLast, newPay );
std::cout<<"** Employee index updated"<<std::endl;
}
void LayoffEmployee()
{
int index = GetSelection();
if( employees_[index].GetIsActive() )
{
std::cout << "Laying off employee:\n" << employees_[index] << std::endl;
employees_[index].LayOff();
}
else
{
std::cerr << "Already layed off employee:" << employees_[index] << std::endl;
}
}
void DisplayEmployeeList()
{
std::copy( employees_.begin(), employees_.end(), std::ostream_iterator<Employee>( std::cout, "\n" ) );
}
int GetSelection()
{
std::size_t indexNumber;
std::cout << "Select an employee from the list below by specifying its number:" << std::endl;
DisplayEmployeeList();
do{
while( !std::cin >> indexNumber )
{
std::cin.clear();
std::cin.ignore();
std::cerr << "Select a number..." << std::endl;
}
if( indexNumber >= employees_.size() )
{
std::cerr << "Select a number within range of list below:" << std::endl;
DisplayEmployeeList();
}
}
while( indexNumber >= employees_.size() );
return indexNumber;
}
Employee& operator[]( std::size_t index )
{
return employees_[index];
}
const Employee& operator[]( std::size_t index ) const
{
return employees_[index];
}
std::size_t EmployeeCount() const
{
return employees_.size();
}
private:
std::vector<Employee> employees_;
};
int main( int argc, char* argv[] )
{
return 0;
}
Finally - the code is merely compiled, not tested. I suspect I might have made a mistake, but alas, time!!!

0xC0000005: Access violation reading location 0xccccccd0. C++

I'm having the above issue when I attempt to set a string (stored in a class) equal to another string. I have combed and combed trying to find if I did not initialize any variables, but I can't find such a situation. In debug mod, I get the above error. In release mode it hangs and Win7 looks for a problem, no major abort or retry window. Here's the relevant code, there is another header file with my main program if you feel it should be included, I'll include the line that causes errors. Language is C++ obviously.
//Error occurs in this area:
Car one;
one = two;
one.addExtra ("Windows");
log << "Car one: " << one << endl;
two = Car(one); // call copy constructor.
//I realize when I call the first one = two, there are no extras
//stored int Car one, which is what differs between the two. Remaining
//code. Extras header:
#include <iostream>
#include <string>
#include <string.h>
using namespace std;
class Extras
{
public:
friend class Car;
friend int main();
friend ostream& operator << (ostream& os, const Extras& in);
friend class CarLot;
Extras(const Extras& other);
Extras& operator=(Extras &rhs);
Extras(string in);
Extras();
~Extras();
void modify_ext(string* in);
//string ex_list;
private:
int place;
string *ex_list;
};
//Extras.cpp:
#include "Extras.h"
Extras::Extras(string in)
{
delete ex_list;
ex_list = new string;
place = 0;
//ex_list = new string[4];
(*ex_list) = in;
place++;
}
Extras::Extras()
{
//ex_list = new string[4];
place = 0;
//for(int i = 0; i < 4; i++)
ex_list = new string;
*ex_list = "0";
}
//Overloaded << operator for Extras class to
//easily output array contents
ostream& operator<< (ostream& os, Extras const &in)
{
os << *(in.ex_list);
return os;
}
Extras& Extras::operator=(Extras &rhs)
{
if(this != &rhs)
{
//string temp;
//temp = rhs.ex_list;
modify_ext(rhs.ex_list);
cout << endl << endl << ex_list << endl << endl;
place = rhs.place;
}
return *this;
}
Extras::Extras(const Extras& other) : place(other.place), ex_list(other.ex_list)
{
//for(int i = 0; i < 4; i++)
//ex_list = other.ex_list;
}
void Extras::modify_ext(string* in)
{
delete ex_list;
ex_list = new string;
(*ex_list).resize((*in).size());
for(unsigned int i = 0; i < (*in).size(); i++)
ex_list[i] = in[i];
}
Extras::~Extras()
{
delete ex_list;
place = 0;
}
//Car Header:
#include "Extras.h"
class Car
{
public:
friend class Extras;
friend Extras& Extras::operator=(Extras &rhs);
friend int main();
friend ostream& operator<< (ostream& os, const Car& in);
friend class CarLot;
friend void add_extra();
~Car();
Car();
Car(Car& other);
Car(string in_name, int in_year, string in_color, float in_cost);
Car& operator=(Car const &rhs);
void edit_extr(int in);
void addExtra(string in);
private:
string name, color;
int year, extr_num;
float cost;
Extras *extr;
};
//Car.cpp:
#include "car.h"
//Constructor
Car::Car(string in_name, int in_year, string in_color, float in_cost)
{
name = in_name;
color = in_color;
year = in_year;
cost = in_cost;
extr = new Extras[3];
extr_num = 0;
}
//Overloaded = operator
Car& Car::operator=(Car const &rhs)
{
if(this != &rhs)
{
name = rhs.name;
color = rhs.color;
year = rhs.year;
cost = rhs.cost;
//delete extr;
extr = rhs.extr;
extr_num = rhs.extr_num;
}
return *this;
}
//Default Constructor
Car::Car()
{
name = "TEMP";
color = "BLUE";
year = 0;
cost = 0;
extr = new Extras[3];
extr_num = 0;
}
//Destructor
Car::~Car()
{
delete extr;
extr = NULL;
}
//Copy constructor
Car::Car(Car& other) : name(other.name), color(other.color), year(other.year),
cost(other.cost), extr_num(other.extr_num)
{
//delete extr;
for(int i = 0; i < extr_num; i++)
{
extr[i].modify_ext(other.extr[i].ex_list);
extr[i].place = other.extr[i].place;
}
}
//Overloaded << operator for Car class
ostream& operator<< (ostream& os, const Car& in)
{
os.precision(2);
os << in.name << ", " << in.year << ", "
<< in.color << ", $"<< in.cost << ", ";
os << "extras include: ";
for(int k = 0; k < in.extr_num; k++)
{
os << in.extr[k] << ", ";
}
os << endl;
return os;
}
void Car::edit_extr(int in)
{
Extras* temp;
temp = new Extras[in];
for(int i = 0; i < in; i++)
temp[i] = extr[i];
extr_num = in;
delete extr;
extr = temp;
}
void Car::addExtra(string in)
{
if(extr_num == 3)
{
//log << "Car has too many extras.";
return;
}
//edit_extr(extr_num + 1);
*(extr[extr_num].ex_list) = in;
extr[extr_num].place++;
extr_num++;
}
As I said, I have one more additional header, another class, and a main program if those need to be included, but I figured this was more than enough code (sorry!) for anyone to look through. Any help would be incredibly appreciated.
What I'm seeing that's broken:
two = Car(one); // call copy constructor.
No, it creates a temporary object with the copy constructor, passes this to operator=() on two, then destroys the temporary.
Extras& operator=(Extras &rhs);
should be:
Extras& operator=(const Extras &rhs);
Extras::Extras(string in)
{
delete ex_list;
ex_list = new string;
place = 0;
//ex_list = new string[4];
(*ex_list) = in;
place++;
}
Better:
Extras::Extras(const string& in): place(1), ex_list(new string(in))
{
}
Extras::Extras(const Extras& other) : place(other.place), ex_list(other.ex_list)
{
//for(int i = 0; i < 4; i++)
//ex_list = other.ex_list;
}
Looking at your default constructor, it's clear that the Extras object owns the string in ex_list. However, this copy constructor claims ownership of the original object's ex_list. It should make its own copy:
Extras::Extras(const Extras& other): place(other.place),
ex_list(new string(other.ex_list))
{
}
void Extras::modify_ext(string* in)
{
delete ex_list;
ex_list = new string;
(*ex_list).resize((*in).size());
for(unsigned int i = 0; i < (*in).size(); i++)
ex_list[i] = in[i];
}
You're copying the string. All you need is:
void Extras::modify_ext(const string* in)
{
*ex_list = *in;
}
Moving on to the Car...
friend class Extras;
friend Extras& Extras::operator=(Extras &rhs);
friend int main();
friend ostream& operator<< (ostream& os, const Car& in);
friend class CarLot;
friend void add_extra();
You should consider refactoring the code to get rid of these.
Car(Car& other);
Car(string in_name, int in_year, string in_color, float in_cost);
Should be:
Car(const Car& other);
Car(const string& in_name, int in_year, const string& in_color, float in_cost);
References are your friends when passing objects to functions.
I'm going to stop here.
In your constructor you are deleting ex_list. It hasn't even been allocated yet, so this is wrong. Remove that and do this instead when allocating your new string:
ex_list = new string(in);
This way you use the string copy constructor. You can get rid of the rest of whatever you were trying to do below in the constructor since this will do it for you.
Edit:
Actually, there are a ton of problems all throughout this code. Is there any reason you want your string to be a pointer internally? You aren't using pointers correctly in a bunch of different places. I only noticed the first one as I scrolled down.
The allocator in debug builds with VC++ uses some magic values to fill allocated areas. In particular, 0xCC is memory that had been allocated but it now freed. So the address 0xCCCCCCD0, looks suspiciously like a small offset (e.g., to a struct or class member) from a pointer in memory that was freed. Given that, Mark Loeser's answer looks promising.