-3

I have four parts to this code. One of them is a DVD class and the others are HarryPotterDVD.h, HarryPotterDVD.cpp and HarryPotterDVDDriver.cpp. When I compile the code, it compiles without giving me any errors whatsoever, but when I try to run the compiled executable, I get an Abort(core dumped) error. I think it is because of the way I used the inherited functions. Could you guys please help me figure out how to solve the problem.

DVD.cpp

#include "DVD.h"

DVD::DVD() {
    id =0;
    title = new char[1];
    title[0] = '\0';
    director = new char[1];
    director[0] = '\0';
}

DVD::DVD(unsigned int i, const char* t, const char* dir) {
    id = i;
    int len;
    for(len = 0; t[len] !='\0'; ++len);
    title = new char[len+1];
    for(int i = 0; i < len+1; i++) {title[i]=t[i];}

    int len2;
    for(len2=0; dir[len2] !='\0'; ++len2);
    director = new char[len2+1];
    for(int j = 0; j<len2+1; j++) {director[j] = dir[j];}
}

DVD::DVD(const DVD &d): id(d.id) {
    int len;
    for(len=0; d.title[len] !='\0'; ++len);
    title = new char[len+1];
    for(int j = 0; j < len+1; j++) {
        title[j] = d.title[j];
    }

    int len2;
    for(len2=0; d.director[len2] != '\0'; ++len2);
    director = new char[len2+1];
    for(int j = 0; j<len2 +1; j++) {
        director[j] = d.director[j];
    }
}

DVD::~DVD() {
    if (title) {
        delete [] title;
    }
    if (director) {
        delete [] director;
    }
}

int DVD::getID() {
    return id;
}

char* DVD::getTitle() {
    return title;
}

char* DVD::getDirector() {
    return director;
}

void DVD::display() {
    cout << '[' << id << '.' << ' ' << title << '/' << director << ']' << endl;
}

void DVD::setID(unsigned int i) {
    id = i;
}

void DVD::setTitle(const char* t) {
    delete [] title;
    int len;
    for(len = 0; t[len] !='\0'; ++len);
    title = new char[len+1];
    for(int i = 0; i < len+1; i++) {title[i]=t[i];}
}

void DVD::setDirector(const char* dir) {
    delete [] director;
    int len2;
    for(len2=0; dir[len2] !='\0'; ++len2);
    director = new char[len2+1];
    for(int j = 0; j<len2+1; j++) {director[j] = dir[j];}    
}

DVD& DVD::operator= (const DVD& arg) {
    id = arg.id;

    int len;
    for(len = 0; arg.title[len] !='\0'; ++len);
    title = new char[len+1];
    for(int i = 0; i < len+1; i++) {title[i]=arg.title[i];}

    int len2;
    for(len2=0; arg.director[len2] !='\0'; ++len2);
    director = new char[len2+1];
    for(int j = 0; j<len2+1; j++) {director[j] = arg.director[j];}  
    return *this;
}

HarryPotterDVD.h

#ifndef _HarryPotterDVD_
#define _HarryPotterDVD_
#include<iostream>
#include "DVD.h"
using namespace std;

class HarryPotterDVD : public DVD {
        int episode;
        char * antagonist;
    public:
        HarryPotterDVD(unsigned int i, char* t, char* dir, int n, char* ant);
        HarryPotterDVD();
        HarryPotterDVD(HarryPotterDVD& d);
        ~HarryPotterDVD();
        int getEpisode();
        char* getAntagonist();
        void display();
        void setEpisode(unsigned int e);
        void setAntagonist(const char* c);
        HarryPotterDVD& operator= (HarryPotterDVD& arg);
};
#endif

HarryPotterDVD.cpp

#include "HarryPotterDVD.h"
#include<iostream>
using namespace std;

HarryPotterDVD::HarryPotterDVD(unsigned int i, char* t, char* dir, int n, char* ant): DVD( i , t , dir) {
    episode = n;
    int len;
    for(len = 0; ant[len] !='\0'; ++len);
    antagonist = new char[len+1];
    for(int j = 0; j < len+1; j++) {antagonist[j]=ant[j];}
}

HarryPotterDVD::HarryPotterDVD(HarryPotterDVD &d) {
    DVD::setID(d.DVD::getID());
    DVD::setTitle(d.DVD::getTitle());
    DVD::setDirector(d.DVD::getDirector());
    episode = d.episode;
    int len;
    for(len = 0; d.antagonist[len] != '\0'; len++);
    antagonist = new char[len + 1];
    for(int i = 0; i < len; i++){
        antagonist[i] = d.antagonist[i];
    }
    antagonist[len+1] = '\0';
}

HarryPotterDVD::HarryPotterDVD() {
    episode = -1;
    char* tmp = "";
    antagonist = tmp;
}

HarryPotterDVD::~HarryPotterDVD(){
    delete [] antagonist;
}

int HarryPotterDVD::getEpisode(){
    return episode;
}

char * HarryPotterDVD::getAntagonist(){
    return antagonist;
}

void HarryPotterDVD::display(){
    cout << "[" << DVD::getID() << ". HP" << episode;
    cout << ":" << DVD::getTitle() << "/" << DVD::getDirector();
    cout << "/" << antagonist << "]" << endl; 
}

void HarryPotterDVD::setEpisode(unsigned int e){
    episode = e;
}

void HarryPotterDVD::setAntagonist(const char * c){
    delete [] antagonist;
    int len;
    for(len = 0; c[len] != '\0'; len++);
    antagonist = new char[len + 1];
    for(int i = 0; i < len; i++){
        antagonist[i] = c[i];
    }
    antagonist[len+1] = '\0';
}

HarryPotterDVD& HarryPotterDVD::operator= (HarryPotterDVD &d){
    delete [] antagonist;
    episode = d.episode;

    int len3;
    for(len3 = 0; d.antagonist[len3] != '\0'; len3++);
    antagonist = new char[len3 + 1];
    for(int i = 0; i < len3; i++){
        antagonist[i] = d.antagonist[i];
    }
    antagonist[len3+1] = '\0';
    DVD::operator=(d);
    /*
    setID(d.getID());
    int len;
    for(len = 0; d.getTitle()[len] != '\0'; len++);
    char * tit = new char[len+1];
    for(int i = 0; i < len; i++){
        tit[i] = d.getTitle()[i];
    }
    tit[len] = '\0';
    setTitle(tit);
    int len2;
    for(len2 = 0; d.getDirector()[len2] != '\0'; len2++);
    char* dire = new char[len2+1];
    for(int i = 0; i < len2; i++){
        dire[i] = d.getDirector()[i];
    }
    dire[len2] = '\0';
    setDirector(dire);
    */
    return* this;
}

HarryPotterDVDDriver.cpp

#include<iostream>
using namespace std;
#include"DVD.h"
#include"HarryPotterDVD.h"

int main() {
    HarryPotterDVD h1;
    HarryPotterDVD h2(1, "Chamber of Secrets", "Chris Columbus", 2, "Tom Riddle");
    HarryPotterDVD h3(h2);
    h1 = h3;
    cout << h2.getEpisode() << endl;
    cout << h2.getAntagonist() << endl;
    h3.display();
    h1.setEpisode(5);
    h1.setAntagonist("Prabesh");
    h1.display();
}
Prabesh
  • 40
  • 5
  • Could you provide the code for `DVD.h`? Also, which compiler are you using, and what compiler version is it? – Alecto Irene Perez Apr 15 '19 at 04:56
  • Could you whittle the problem down to a [mcve]? – Gardener Apr 15 '19 at 05:01
  • At least you’re missing a null termination in the constructor. Is it really needed to do all this work manually? If so, at least make it a function and don’t repeat it all around and get errors. Also step through the code line by line with a debugger to see where the problem occurs. – Sami Kuhmonen Apr 15 '19 at 05:04
  • 1
    Compiling a program successfully means that the program is syntactically correct. That doesn't mean that the program is free of errors and code with [Undefined Behavior](https://stackoverflow.com/a/4105123/1505939). An abort is a sure sign for that (although no abort doesn't mean anything). Hence, the next step is debugging. Most IDEs support visual debugging but command line debuggers like `gdb` are an alternative which might be powerful as well. – Scheff's Cat Apr 15 '19 at 05:39
  • Your title says when compiling. Your question says the opposite. Make up your mind. – user207421 Apr 15 '19 at 07:16

1 Answers1

0

In the default constructor of HarryPotterDVD, you are assigning a random pointer to member variable antagonist which is not created with new[]

HarryPotterDVD::HarryPotterDVD() {
    episode = -1;
    char* tmp = "";
    antagonist = tmp;
}

In the operator=()function, when the statement h1=h3; is being executed, you are deleting the antagonist using delete[] which is causing the segmentation fault.

delete is null-safe. So, in your default constructors, you can just make the pointers to nullptr and delete of them during assigning won't cause any errors. If you change this way, your issue should go away.

HarryPotterDVD::HarryPotterDVD() {
    episode = -1;
    antagonist = nullptr;

}

Wander3r
  • 1,801
  • 17
  • 27