Good evening.
Code:
thames@semaht ~/C++/Projects/Disks $ g++ -g -Wall maindisk1.cpp disk1.cpp -o maindisk1 -std=c++11
thames@semaht ~/C++/Projects/Disks $ valgrind ./maindisk1
==2721== Memcheck, a memory error detector
==2721== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==2721== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==2721== Command: ./maindisk1
==2721==
Using object directly:
Label: Capitol
Performers: Beatles
Number of selections: 14
Playtime: 35.50
Primary work: Piano Sonata in B flat, Fantasia in C
Label: Philips
Performers: Alfred Brendel
Number of selections: 2
Playtime: 57.17
Using type cd * pointer to objects:
Label: Capitol
Performers: Beatles
Number of selections: 14
Playtime: 35.50
Primary work: Piano Sonata in B flat, Fantasia in C
Label: Philips
Performers: Alfred Brendel
Number of selections: 2
Playtime: 57.17
Calling a function with a Cd reference argument:
Label: Capitol
Performers: Beatles
Number of selections: 14
Playtime: 35.50
Primary work: Piano Sonata in B flat, Fantasia in C
Label: Philips
Performers: Alfred Brendel
Number of selections: 2
Playtime: 57.17
Testing assignment:
==2721== Conditional jump or move depends on uninitialised value(s)
==2721== at 0x401292: Cd::operator=(Cd const&) (disk1.cpp:72)
==2721== by 0x40163C: Classic::operator=(Classic const&) (disk1.cpp:117)
==2721== by 0x400DA3: main (maindisk1.cpp:27)
==2721==
==2721== Conditional jump or move depends on uninitialised value(s)
==2721== at 0x4C2A07A: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2721== by 0x4012A3: Cd::operator=(Cd const&) (disk1.cpp:72)
==2721== by 0x40163C: Classic::operator=(Classic const&) (disk1.cpp:117)
==2721== by 0x400DA3: main (maindisk1.cpp:27)
==2721==
==2721== Invalid free() / delete / delete[] / realloc()
==2721== at 0x4C2A0C7: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2721== by 0x4012A3: Cd::operator=(Cd const&) (disk1.cpp:72)
==2721== by 0x40163C: Classic::operator=(Classic const&) (disk1.cpp:117)
==2721== by 0x400DA3: main (maindisk1.cpp:27)
==2721== Address 0x40189d is in the Text segment of /home/thames/C++/Projects/Disks/maindisk1
==2721==
==2721== Conditional jump or move depends on uninitialised value(s)
==2721== at 0x4012F1: Cd::operator=(Cd const&) (disk1.cpp:75)
==2721== by 0x40163C: Classic::operator=(Classic const&) (disk1.cpp:117)
==2721== by 0x400DA3: main (maindisk1.cpp:27)
==2721==
==2721== Conditional jump or move depends on uninitialised value(s)
==2721== at 0x4C2A07A: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2721== by 0x401302: Cd::operator=(Cd const&) (disk1.cpp:75)
==2721== by 0x40163C: Classic::operator=(Classic const&) (disk1.cpp:117)
==2721== by 0x400DA3: main (maindisk1.cpp:27)
==2721==
==2721== Invalid free() / delete / delete[] / realloc()
==2721== at 0x4C2A0C7: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2721== by 0x401302: Cd::operator=(Cd const&) (disk1.cpp:75)
==2721== by 0x40163C: Classic::operator=(Classic const&) (disk1.cpp:117)
==2721== by 0x400DA3: main (maindisk1.cpp:27)
==2721== Address 0x4e3c998 is not stack'd, malloc'd or (recently) free'd
==2721==
==2721== Conditional jump or move depends on uninitialised value(s)
==2721== at 0x401648: Classic::operator=(Classic const&) (disk1.cpp:118)
==2721== by 0x400DA3: main (maindisk1.cpp:27)
==2721==
==2721== Conditional jump or move depends on uninitialised value(s)
==2721== at 0x4C2A07A: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2721== by 0x401659: Classic::operator=(Classic const&) (disk1.cpp:118)
==2721== by 0x400DA3: main (maindisk1.cpp:27)
==2721==
==2721== Invalid free() / delete / delete[] / realloc()
==2721== at 0x4C2A0C7: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2721== by 0x401659: Classic::operator=(Classic const&) (disk1.cpp:118)
==2721== by 0x400DA3: main (maindisk1.cpp:27)
==2721== Address 0x400b30 is in the Text segment of /home/thames/C++/Projects/Disks/maindisk1
==2721==
Primary work: Piano Sonata in B flat, Fantasia in C
Label: Philips
Performers: Alfred Brendel
Number of selections: 2
Playtime: 57.17
==2721==
==2721== HEAP SUMMARY:
==2721== in use at exit: 0 bytes in 0 blocks
==2721== total heap usage: 8 allocs, 11 frees, 138 bytes allocated
==2721==
==2721== All heap blocks were freed -- no leaks are possible
==2721==
==2721== For counts of detected and suppressed errors, rerun with: -v
==2721== Use --track-origins=yes to see where uninitialised values come from
==2721== ERROR SUMMARY: 9 errors from 9 contexts (suppressed: 2 from 2)
Code:
#ifndef DISK1_H_
#define DISK1_H_
// base class
class Cd // represents a CD disk
{
private:
char* performers;
char* label;
int selections;
// number of selections
double playtime; // playing time in minutes
public:
Cd(){}
Cd(const char* pfs, const char* lbl, const int sls, const double pte);
Cd(const Cd & c);
virtual ~Cd();
virtual void Report() const; // reports all CD data
Cd& operator=(const Cd & c);
};
class Classic : public Cd
{
private:
char* primary_work;
public:
Classic() {}
Classic(const char* p_work, const char* pfs,
const char* lbl, const int sls,const double pte);
Classic(const char* p_work, const Cd& c);
Classic(const Classic& cl);
virtual ~Classic();
virtual void Report() const;
Classic& operator=(const Classic& cl);
};
#endif
Code:
// implements interface disk1.h
#include "Headers/disk1.h"
#include <iostream>
#include <cstring>
#include <cstdlib>
using std::cout;
using std::strlen;
using std::strcpy;
using std::ios_base;
using std::endl;
typedef std::ios_base::fmtflags Format;
typedef std::streamsize Precis;
Cd::Cd(const char* pfs, const char* lbl, const int sls, const double pte)
{
performers = new char[strlen(pfs) + 1];
strcpy(performers, pfs);
label = new char[strlen(lbl) + 1];
strcpy(label, lbl);
if(sls > 0 && sls <= 20)
selections = sls;
else
{
cout << "Selections must be a value between 1 and 20";
exit(EXIT_FAILURE);
}
if(pte > 2.0 && pte < 60.0)
playtime = pte;
else
{
cout << "Playtime must be a value between 2 and 60 with fraction point";
exit(EXIT_FAILURE);
}
}
Cd::Cd(const Cd& c)
{
performers = new char[strlen(c.performers) + 1];
strcpy(performers, c.performers);
label = new char[strlen(c.label) + 1];
strcpy(label, c.label);
selections = c.selections;
playtime = c.playtime;
}
Cd::~Cd()
{
delete[] performers;
delete[] label;
}
void Cd::Report() const
{
Format initial = cout.setf(ios_base::fixed, ios_base::floatfield);
Precis prec = cout.precision(2);
cout << "Label: " << label << endl;
cout << "Performers: " << performers << endl;
cout << "Number of selections: " << selections << endl;
cout << "Playtime: " << playtime << endl;
cout.setf(initial);
cout.precision(prec);
}
Cd& Cd::operator=(const Cd& c)
{
if(this == &c)
return *this;
delete[] performers;
performers = new char[strlen(c.performers) + 1];
strcpy(performers, c.performers);
delete[] label;
label = new char[strlen(c.label) + 1];
strcpy(label, c.label);
selections = c.selections;
playtime = c.playtime;
return *this;
}
Classic::Classic(const char* p_work, const char* pfs, const char* lbl,
const int sls, const double pte) : Cd(pfs, lbl, sls, pte)
{
primary_work = new char[strlen(p_work) + 1];
strcpy(primary_work, p_work);
}
Classic::Classic(const char* p_work, const Cd& c) : Cd(c)
{
primary_work = new char[strlen(p_work) + 1];
strcpy(primary_work, p_work);
}
Classic::Classic(const Classic& cl) : Cd(cl)
{
primary_work = new char[strlen(cl.primary_work) + 1];
strcpy(primary_work, cl.primary_work);
}
Classic::~Classic()
{
delete[] primary_work;
}
void Classic::Report() const
{
cout << "Primary work: " << primary_work << endl;
Cd::Report();
}
Classic& Classic::operator=(const Classic& cl)
{
if(this == &cl)
return *this;
Cd::operator=(cl);
delete [] primary_work;
primary_work = new char[strlen(cl.primary_work) + 1];
strcpy(primary_work, cl.primary_work);
return *this;
}
Code:
// main program -- compile with disk1.cpp
#include <iostream>
using namespace std;
#include "Headers/disk1.h"
void Bravo(const Cd & disk);
int main()
{
Cd c1("Beatles", "Capitol", 14, 35.5);
Classic c2 = Classic("Piano Sonata in B flat, Fantasia in C",
"Alfred Brendel", "Philips", 2, 57.17);
Cd *pcd = &c1;
cout << "Using object directly:\n";
c1.Report();
// use Cd method
c2.Report();
// use Classic method
cout << "Using type cd * pointer to objects:\n";
pcd->Report(); // use Cd method for cd object
pcd = &c2;
pcd->Report(); // use Classic method for classic object
cout << "Calling a function with a Cd reference argument:\n";
Bravo(c1);
Bravo(c2);
cout << "Testing assignment: " << endl;
Classic copy;
copy = c2;
copy.Report();
return 0;
}
void Bravo(const Cd & disk)
{
disk.Report();
}