-1
#include <iostream>
#include <cstring>
#include <string>

class Cd {
private:
    const char* performers;
    const char* label;
    int selections;
    double playtime;
public:
    Cd(){
        int eight = 8;
        performers = new char[eight];
        label = new char[eight];
        label = "Unknown";
        performers = "Unknown";
        selections = 0;
        playtime = 0.0;
    }
    Cd(const char* performers, const char* label, int selections, double playtime) {
        this->performers = new char[strlen(performers)+1];
        this->performers = performers;
        this->label = new char[strlen(label) + 1];
        this->label = label;
        this->selections = selections;
        this->playtime = playtime;

    }
    void setLabel(const char* label) {
        this->label = label;

    }
    void setPerformers(const char* performers) {
        this->performers = performers;

    }
    void setSelections(int selections) {
        this->selections = selections;

    }
    void setPlaytime(double playtime) {
        this->playtime = playtime;

    }
    const char* getLabel() {
        return label;
    }
    const char* getPerformers() {
        return performers;
    }
    int getSelections() {
        return selections;
    }
    double getPlaytime() {
        return playtime;
    }
   

    virtual void Report() {
        std::cout << "Performers: " << performers<<std::endl
         <<"Label: " <<label<< std::endl
        <<"Number of selections: " << selections << std::endl
        <<"Play time: " << playtime << std::endl;

    }

    ~Cd() {
        delete[] performers;
        delete[] label;

    }
};

class Classic : public Cd {
private:
    const char* primaryWork;
public:
    Classic() {
        primaryWork = new char[8];
        primaryWork = "Unknown";
    
    }

    Classic(const char* primaryWork, const char* performers, const char* label, int selections, double playtime) {
        this->primaryWork = new char[strlen(primaryWork) + 1];
        this->primaryWork = primaryWork;
        setLabel(label);
        setPerformers(performers);
        setSelections(selections);
        setPlaytime(playtime);
    }
    virtual void Report() {
        std::cout << "Primary work: " << primaryWork << std::endl<< 
            "Performers: " << getPerformers() << std::endl <<
            "Label: " <<getLabel()  << std::endl<<
            "Number of selections: " << getSelections() << std::endl
            << "Play time: " << getPlaytime() << std::endl;
    
    }
    ~Classic() {
        delete[] primaryWork;

    };

};
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* parent = &c1;
            std::cout << "\nUsing object directly:\n";
        std::cout << "***************************" << std::endl;

        c1.Report();
        c2.Report();
 
        std::cout << "\nUsing type cd * pointer to objects:\n";
        std::cout << "***************************" << std::endl;

        // Call Report() using Cd type pointer created above 
        parent->Report();
        Classic* classic = &c2;
        classic->Report();

        // Call Report() using Cd type pointer containing Classic object address 

        return 0;
    
}

I don't understand what is wrong with the delete keyword. My code is supposed to delete the memory allocation for the array at the end to save memory, but it is not working. The delete_scalar file pops up and the code does not finish executing. The rest of the code is working fine. The big problem is when I build the code the compiler tells me that there are no errors found.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 2
    https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three overload copy constructor and assignment operator properly. – πάντα ῥεῖ Mar 16 '22 at 17:27
  • 2
    Using `new`, assigning the result to a `const char *`, then immediately setting that `const char *` to a literal string does not really do what you think it does, that's the problem. Your C++ textbook should have examples of doing that: using new to allocate a buffer of characters then populating it. Is that how your C++ textbook's example does this? – Sam Varshavchik Mar 16 '22 at 17:27
  • Off-Topic: If you use a different naming scheme between members and parameters, you won't need to use the `this->` syntax. – Thomas Matthews Mar 16 '22 at 17:27
  • 2
    `primaryWork = new char[8]; primaryWork = "Unknown";` allocates some memory and then leaks it by assigning the pointer to a string literal which cannot be deleted since it was not allocated with `new`. Use `strcpy` to copy the string into the allocated memory if that is your intent. Consider using `std::string` instead of manual dynamic allocation. – Retired Ninja Mar 16 '22 at 17:27
  • 1
    Prefer to use `std::string` and you can eliminate a lot of dynamic memory issues. – Thomas Matthews Mar 16 '22 at 17:28
  • 2
    Well, you can fail a written test if you write nonsense, even if your grammar is impeccable... – molbdnilo Mar 16 '22 at 17:29
  • The fact you mention Alfred Brendel motivates me to answer this - my very accomplished violinist wife has worked with him, along with his boy Adrian. Upvoting for that! – Bathsheba Mar 16 '22 at 17:34
  • @ThomasMatthews: Exactly! I still use `m_` for class members and `s_` for statics. Indeed syntax highlighters somewhat reduce the need for that, but alas *vi* doesn't support them and occasionally one has to resort to using *vi* as your editor. – Bathsheba Mar 16 '22 at 17:38

1 Answers1

1

Write

std::string performers;

instead of

const char* performers;

and so on for the other string-like members. Then you can drop the new[] and delete[] entirely. The bug you have is a reassignment of the pointer to some read-only const char[] type "Unknown" which compiles due to the rules of pointer decay.

Using bare pointers for class members also means you need to write constructors, a destructor, and an assignment operator correctly. If you use std::string then you can rely on the compiler-generated ones.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483