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); }; #endifCode:// 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(); }



11Likes
LinkBack URL
About LinkBacks




At least, I've been learning some principles of C++. He has been using char* and char[] a lot, I admit. Based on what you told me and the review I found, I couldn't decide what to do until the programs using std::string started to appear. (there are some of then too). My guess is that he shows both sides of the coin so the C++ principles get stuck in your head (I think).