I am getting Memory Leak error. Note: I got the output I want but there is memory leak at the end(Compile with Valgrind(it is memory leak checking tool)) In total I have 5 Files
main.cpp
#include<iostream>
#include "Minister.h"
#include "Minister.h" // intentional
#include "MemberParliament.h"
#include "MemberParliament.h" // intentional
using namespace std;
using namespace sdds;
void printHeader(const char* title)
{
char oldFill = cout.fill('-');
cout.width(62);
cout << "" << endl;
cout << "|> " << title << endl;
cout.fill('-');
cout.width(62);
cout << "" << endl;
cout.fill(oldFill);
}
void newElections(Minister& aMinister, const char* district, const char* newPM, double year)
{
aMinister.NewDistrict(district);
aMinister.changePM(newPM);
aMinister.assumeOffice(year);
cout << "Status of New Election " << aMinister << endl << endl;
}
int main()
{
printHeader("Person 1: MemberParliament");
MemberParliament mp("MP9403", 59);
cout << mp << endl << endl;
mp.NewDistrict("Scarborough");
mp.NewDistrict("Mississauga");
mp.NewDistrict("Huron County");
cout << endl << mp << endl << endl;
printHeader("Person 2: Read/Write");
cin >> mp;
cout << endl << mp << endl << endl;
printHeader("Person 3: Minister");
Minister aMinister("MP9573", 63, 2003, "Harper", "Pickering");
cout << endl;
newElections(aMinister, "Whitby", "Trudeau", 2007);
newElections(aMinister, "Kitchener", "Biden", 2010);
newElections(aMinister, "Oakville", "Trump", 2015);
printHeader("Person 4: Read/Write");
cin >> aMinister;
cout << endl << (MemberParliament)aMinister;
cout << endl << aMinister << endl << endl;
return 0;
}
Minister.h
#ifndef SDDS_MINISTER_H
#define SDDS_MINISTER_H
#include <iostream>
#include "MemberParliament.h"
namespace sdds{
class Minister : public MemberParliament{
private:
char *pm;
double year;
public:
//a custom constructor that receives the following information about the Minister: idd, age, the year assumed office, district, and name of the prime minister. Call the constructor from the base class and pass the relevant data to it. update the private data members of the Minister accordingly
Minister(const char* id, int age, int year, const char* newPM,const char* newDistrict);
~Minister();
void changePM(const char* pm);
void assumeOffice(double year);
std::ostream& write(std::ostream& os);
std::istream& read(std::istream& in);
};
//overload the insertion and extraction operators to insert a Minister into a stream and extract a Minister from a stream. These operators should call the write/read member functions in the class Minister.
std::ostream& operator<<(std::ostream& os,const Minister& min);
std::istream& operator>>(std::istream& in, Minister& min);
}
#endif // SDDS_MINISTER_H
Minister.cpp
#include <iostream>
#include <string.h>
#include "Minister.h"
#include "MemberParliament.h"
using namespace std;
namespace sdds
{
// implement base class constructor with child class constructor
Minister::Minister(const char* id, int age, int year, const char* newPM,const char* newDistrict) : MemberParliament(id, age, newDistrict){
this->year = year;
this->pm = new char[strlen(newPM) + 1];
strcpy(this->pm, newPM);
}
void Minister::changePM(const char *pm)
{
delete[] this->pm;
this->pm = new char[strlen(pm) + 1];
strcpy(this->pm, pm);
}
void Minister::assumeOffice(double year)
{
this->year = year;
}
std::ostream &Minister::write(std::ostream &os)
{
MemberParliament::write(os);
os <<" |" <<" " << this->pm << "/" << this->year;
return os;
}
std::istream &Minister::read(std::istream &in)
{
MemberParliament::read(in);
cout << "Reports TO: ";
in >> this->pm;
cout << "Year Assumed Office: ";
in >> this->year;
return in;
}
std::ostream &operator<<(std::ostream &os,const Minister &min)
{
Minister temp = min;
temp.write(os);
return os;
}
std::istream &operator>>(std::istream &in, Minister &min)
{
min.read(in);
return in;
}
Minister::~Minister()
{
//delete[] this->pm;
}
}
MemberParliament.h
#ifndef SDM_MEMBERPARLAMENT_H
#define SDM_MEMBERPARLAMENT_H
#include <iostream>
using namespace std;
namespace sdds{
class MemberParliament{
private:
char *p_id;
char *district;
int mp_age;
public:
//A custom constructor that receives as parameters the MP Id and age. Set the district the MP represents as Unassigned. Assume all data is valid.
MemberParliament(const char* id, int age);
MemberParliament(const char* id, int age, const char* newDistrict);
~MemberParliament();
void NewDistrict(const char* district);
ostream& write(ostream& os);
istream& read(istream& in);
};
std::ostream& operator<<(std::ostream& os,const MemberParliament& mp);
std::istream& operator>>(std::istream& in, MemberParliament& mp);
}
#endif // SDM_MEMBERPARLAMENT_H
MemberParliament.cpp
#include <iostream>
#include <string.h>
#include "Minister.h"
#include "MemberParliament.h"
using namespace std;
namespace sdds
{
MemberParliament::MemberParliament(const char *id, int age, const char *newDistrict)
{
this->p_id = new char[strlen(id) + 1];
strcpy(this->p_id, id);
this->mp_age = age;
this->district = new char[strlen(newDistrict) + 1];
strcpy(this->district, newDistrict);
printf("|%8s| | Unassigned ---> %-23s|\n", this->p_id, district);
}
MemberParliament::MemberParliament(const char *id, int age)
{
//use malloc
this->p_id = new char[strlen(id) + 1];
strcpy(this->p_id, id);
this->mp_age = age;
//set "Unassigned" as default district
this->district = new char[strlen("Unassigned") + 1];
strcpy(this->district, "Unassigned");
}
void MemberParliament::NewDistrict(const char *district)
{
/*print like this:
| MP9403| | Unassigned ---> Scarborough |
| MP9403| | Scarborough ---> Mississauga |
| MP9403| | Mississauga ---> Huron County |
*/
printf("|%8s| |%20s ---> %-23s|\n", this->p_id, this->district, district);
if (this->district != nullptr)
{
delete[] this->district;
}
this->district = new char[strlen(district) + 1];
strcpy(this->district, district);
// if district is "Unassigned", set it to nullptr
}
std::ostream &MemberParliament::write(ostream &os)
{
os << "| " << this->p_id << " | " << this->mp_age << " | " << this->district;
return os;
}
std::istream &MemberParliament::read(istream &in)
{
cout << "Age: ";
in >> this->mp_age;
cout << "Id: ";
in >> this->p_id;
cout << "District: ";
in >> this->district;
return in;
}
// overload the insertion operator to print the MemberParliament object
std::ostream &operator<<(std::ostream &os, const MemberParliament &mp)
{
MemberParliament temp = mp;
temp.write(os);
return os;
}
// overload the extraction operator to read the MemberParliament object
std::istream &operator>>(std::istream &in, MemberParliament &mp)
{
mp.read(in);
return in;
}
MemberParliament::~MemberParliament()
{
// delete[] this->p_id;
// delete[] this->district;
}
}
And here is the error I am getting
==203530==
==203530== HEAP SUMMARY:
==203530== in use at exit: 42 bytes in 5 blocks
==203530== total heap usage: 16 allocs, 11 frees, 72,886 bytes allocated
==203530==
==203530== 6 bytes in 1 blocks are definitely lost in loss record 1 of 5
==203530== at 0x4C2AC38: operator new[](unsigned long) (vg_replace_malloc.c:433)
==203530== by 0x4015F2: sdds::Minister::changePM(char const*) (Minister.cpp:23)
==203530== by 0x400D8B: newElections(sdds::Minister&, char const*, char const*, double) (main_prof.cpp:34)
==203530== by 0x400FC0: main (main_prof.cpp:67)
==203530==
==203530== 7 bytes in 1 blocks are definitely lost in loss record 2 of 5
==203530== at 0x4C2AC38: operator new[](unsigned long) (vg_replace_malloc.c:433)
==203530== by 0x401212: sdds::MemberParliament::MemberParliament(char const*, int) (MemberParliament.cpp:29)
==203530== by 0x400E0A: main (main_prof.cpp:45)
==203530==
==203530== 7 bytes in 1 blocks are definitely lost in loss record 3 of 5
==203530== at 0x4C2AC38: operator new[](unsigned long) (vg_replace_malloc.c:433)
==203530== by 0x401166: sdds::MemberParliament::MemberParliament(char const*, int, char const*) (MemberParliament.cpp:18)
==203530== by 0x401545: sdds::Minister::Minister(char const*, int, int, char const*, char const*) (Minister.cpp:15)
==203530== by 0x400F24: main (main_prof.cpp:60)
==203530==
==203530== 9 bytes in 1 blocks are definitely lost in loss record 4 of 5
==203530== at 0x4C2AC38: operator new[](unsigned long) (vg_replace_malloc.c:433)
==203530== by 0x4012E4: sdds::MemberParliament::NewDistrict(char const*) (MemberParliament.cpp:51)
==203530== by 0x400D78: newElections(sdds::Minister&, char const*, char const*, double) (main_prof.cpp:33)
==203530== by 0x400FC0: main (main_prof.cpp:67)
==203530==
==203530== 13 bytes in 1 blocks are definitely lost in loss record 5 of 5
==203530== at 0x4C2AC38: operator new[](unsigned long) (vg_replace_malloc.c:433)
==203530== by 0x4012E4: sdds::MemberParliament::NewDistrict(char const*) (MemberParliament.cpp:51)
==203530== by 0x400E68: main (main_prof.cpp:50)
==203530==
==203530== LEAK SUMMARY:
==203530== definitely lost: 42 bytes in 5 blocks
==203530== indirectly lost: 0 bytes in 0 blocks
==203530== possibly lost: 0 bytes in 0 blocks
==203530== still reachable: 0 bytes in 0 blocks
==203530== suppressed: 0 bytes in 0 blocks
NOTE: I already tried using destructor but it will increases the errors