Problem z destruktorem

0

Witam,
Mam problem z destruktorem klasy będącej listą, mianowicie mam listę:

class lista
{
    public:
        lista();
        lista(alarm e);
        virtual ~lista();
        void init();
        lista& operator=(lista const &lst);
        lista(lista const &lst);
        friend lista operator+(lista * lst, alarm al);
        friend lista operator+(lista * lst, task tsk);
        //friend lista operator+(lista lst, event * ev);
        bool operator==(lista const &lista);
        bool operator>(lista const &lista);
        bool operator<(lista const &lista);
        friend ostream& operator<<(ostream &out, lista const &lst);

    protected:

    private:
        alarm* first_alarm;
        alarm* last_alarm;
        task* first_task;
        task* last_task;
        //event* first_event;
        //event* last_event;
        int rozmiar_a;
        int rozmiar_t;
        //int rozmiar_e;
};

klasa terminarz zawiera wskaznik na listę, która tworzona jest w bezargumentowym konstruktorze:

class terminarz
{
    public:
        terminarz();
        static int ilosc;
        ~terminarz();
        terminarz(terminarz const &term);
        friend terminarz operator+(terminarz * term, alarm al);
        friend terminarz operator+(terminarz * term, task tsk);
        friend ostream& operator<< (ostream &out,terminarz &trm);
        bool operator==(terminarz const &terminarz);
        bool operator>(terminarz const &terminarz);
        bool operator<(terminarz const &terminarz);
        static int sprawdz_ilosc();

    private:
        lista * zdarzenia;


};
terminarz::terminarz()
{
    #ifdef _DEBUG
    cout<<" konstruktor terminarza\n";
    #endif // _DEBUG
    zdarzenia = new lista();
    ilosc++;
}

w momencie gdy dodaję obiekt alarm do listy:

terminarz trm1;
    alarm * al=  new alarm(12,6,2017,20,30,"xd");
    &trm1+(*al);

przy użyciu następujących przeciążonych operatorów:

terminarz operator+(terminarz * term, alarm alrm)
{

    term->zdarzenia+alrm;
}
lista operator+(lista * lst, alarm al)
{
    if(lst->first_alarm==nullptr)
    {

        lst->first_alarm=new alarm;
        lst->first_alarm[0]=al;
        lst->first_alarm->nast=nullptr;
        lst->last_alarm=lst->first_alarm;
        lst->rozmiar_a++;
        cout<<"dodano alarm\n";
    }
    else
    {
        lst->last_alarm->nast=new alarm;
        lst->last_alarm=lst->last_alarm->nast;
        *(lst->last_alarm)=al;
        lst->last_alarm->nast=nullptr;
        lst->rozmiar_a++;
        cout<<"dodano alarm\n";

    }

}

dostaję segmentation fault związany z obiektem klasy task, który jeszcze ani razu nie został użyty, zatem wskaźnik na first_task jest nullptr zatem w ogóle nie powinno wywoływać delete task:

lista::~lista()
{
    #ifdef _DEBUG
    cout<<"destruktor listy\n";
    #endif // _DEBUG
    if(this->rozmiar_a==0 || this->first_alarm==nullptr)
    {
        #ifdef _DEBUG
        cout<<"brak alarmow do usuniecia\n";
        #endif // _DEBUG
    }
    else
    {
        alarm* nast=this->first_alarm;
        alarm*temp;
        while(nast!=nullptr)
        {
            temp=nast;
            delete temp;
            nast=nast->nast;

        }

    }
    if(this->rozmiar_t==0 || this->first_task==nullptr)
    {
        #ifdef _DEBUG
        cout<<"brak zadan do usuniecia\n";
        #endif // _DEBUG
    }
    else
    {
        task* temp;
        task* nast=this->first_task;
        while(nast!=nullptr)
        {
            temp=nast;
            delete temp;
            nast=nast->nast;

        }

    }

}

task jest prostą klasą bez destruktora gdyż wszytskie jego elementy są statyczne:

class task :public event
{
    public:
        task(int dzien, int miesiac, int rok, int godzina, int minuta, string notatka);
        task();
        bool do_it();
        void check();
        task* nast;
        friend ostream& operator<<(ostream &out,task const &task);
        operator alarm();
        string show();
        bool operator==(task const &task);
        bool operator>(task const &task);
        bool operator<(task const &task);
    private:
        bool done;
        string notatka;
        void remind();
};

nie do końca rozumiem co się dzieje. Gdyż stos wywołań funkcji wygląda tak: main->terminarz operator+(terminarz * term, alarm alrm)->~lista->~task;
nie powstał, żaden obiekt klasy task zatem skąd się wziął wywołany destruktor?

0

Twój kod to UB na UB.

terminarz operator+(terminarz * term, alarm alrm)
{

    term->zdarzenia+alrm;
}

Zdefiniowany operator zwraca obiekt klasy terminarz. Nigdzie tego nie robisz, to UB.

lista operator+(lista * lst, alarm al)
{
// ...
}

Tutaj tak samo z lista - pewnie destruktor obiektu, który powinien być zwrócony z tej funkcji powoduje problemy.

Polecam do lektury:

1 użytkowników online, w tym zalogowanych: 0, gości: 1