c++ reading access violation in copy constructor

I learn c++ and create my own little programm. In my programm I programed a linked list which works. I can link my elements, delete it and print it out. Here is the Code for my linked list.

Rechnung.h

#pragma once
#include <iostream>
#include "Person.h"
#include <ctime>
#include "Datum2.h"
#include <string>

class Rechnung {

private:
    Person person;
    Datum2 datum;
    std::string verwendung;
    double betrag;
    Rechnung* next;

    Person generatePerson();

public:
    //default Konstruktor
    Rechnung() {
        person = generatePerson();
        datum = Datum2();

        betrag = (rand() % 10000) * 0.4;

        verwendung = "DUMMYTEXT";

        next = NULL;
    }

    Rechnung(Datum2& date, Person& person, std::string& verwendung, double betrag)
        :datum(date), person(person), verwendung(verwendung), betrag(betrag)
    {
        next = NULL;
    }
    //getter und Setter
    Person getPerson() const {
        return person;
    }

    Datum2 getDate() const {
        return datum;
    }

    std::string getVerwendung()const {
        return verwendung;
    }

    double getBetrag() {
        return betrag;
    }

    Rechnung* getNext()const {// das nächste Element setzen
        return next;
    }

    void setPerson(Person& p) {
        person = p;
    }

    void setDate(Datum2& date) {
        this->datum = date;
    }

    void setVerwendung(std::string& verwendung) {
        this->verwendung = verwendung;
    }

    void setNext(Rechnung* rechnung) {
        next = rechnung;
    }

    friend std::ostream& operator<<(std::ostream& os, Rechnung& r);
};

Rechnung.cpp

#include "Rechnung.h"

std::string vornamen[4] = { "Dennis", "Jurgen", "Vladimier", "Raisa" };
std::string nachname[4] = { "Semke", "Kastargin", "Schick", "Schmunk" };

Person Rechnung::generatePerson() {

    int vornameIndex = rand() % 4;
    int nachnameIndex = rand() % 4;

    Person person(vornamen[vornameIndex], nachname[nachnameIndex]);
    return person;
}



std::ostream& operator<<(std::ostream& os, Rechnung& r) {

    std::string line(50, '-');
    std::string shortLine(10, '=');
    os << r.datum.asString() << "n" << r.person.getName() << " " << r.person.getNachname() << std::endl;
    os << line << std::endl;
    os << "Verwendungszewck:n" << r.verwendung << "nn";
    os << r.betrag << "n" << shortLine << std::endl;

    return os;
}

std::ostream& operator<<(std::ostream& os, Rechnung* r) {

    std::string line(50, '-');
    std::string shortLine(10, '=');
    os << r->getDate().asString() << "n" << r->getPerson().getName() << " " << r->getPerson().getNachname() << std::endl;
    os << line << std::endl;
    os << "Verwendungszewck:n" << r->getVerwendung() << "nn";
    os << r->getBetrag() << "n" << shortLine << std::endl;

    return os;
}

Rechnungsliste.h

#pragma once
#include "Rechnung.h"
class RechnungsListe {

private:
    Rechnung* first, * last;
    int listLength = 0;

public:
    RechnungsListe();

    //Movekonstruktor
    RechnungsListe(RechnungsListe& liste);
    ~RechnungsListe();

    Rechnung* getFirst() const;
    Rechnung* getLast() const;

    void pushFirst(Rechnung& rechnung);
    void pushLast(Rechnung& rechnung);
    void print();

    bool deleteLast();
    bool deleteFirst();

};

In my next step I want to copy my linked list so I program a copy constructor. My idea is to link only the first and the last element to my copy. It should wotk because the Elements are linked to each other and I only point to begin and end of the list. I just want to find out it will work or not.

Rechnungsliste.cpp

#include "RechnungsListe.h"

RechnungsListe::RechnungsListe() {
    std::cout << "default konstruktor" << std::endl;
    first = NULL;
    last = NULL;
}


RechnungsListe::RechnungsListe(RechnungsListe& liste) {

    std::cout << "Copy constructwird ausgeführt" << std::endl;

    first = liste.getFirst();
    last = liste.getLast();

}
RechnungsListe::~RechnungsListe() {
    std::cout << "Liste loeschen" << std::endl;

    Rechnung* current = last;
    Rechnung* temp;
    while (current != NULL) {
        temp = current;
        current = current->getNext();
        delete temp;
    }
    //std::cout << *last;
}

Rechnung* RechnungsListe::getFirst() const {
    return first;
}

Rechnung* RechnungsListe::getLast() const {
    return last;
}

void RechnungsListe::pushFirst(Rechnung& rechnung) {

    if (first == NULL) {
        first = &rechnung;
        last = &rechnung;
        rechnung.setNext(NULL);
    }
    else {
        first->setNext(&rechnung);
        first = &rechnung;
        rechnung.setNext(NULL);
    }
    listLength++;
}

void RechnungsListe::pushLast(Rechnung& rechnung) {

    Rechnung* temp;
    if (last == NULL) {
        last = &rechnung;
        first = &rechnung;
        rechnung.setNext(NULL);
    }
    else {

        rechnung.setNext(last);
        last = &rechnung;
    }
    listLength++;

    //std::cout << *last << *last->getNext();
}

void RechnungsListe::print() {
    int index = 0;
    Rechnung* current = last;
    std::cout << "AUSGABE DER LISTEnn";
    while (current != NULL) {

        std::cout << index << "n" << *current;
        current = current->getNext();
        index++;
    }
}

bool RechnungsListe::deleteFirst() {

    Rechnung* current = last;
    while (current != NULL) {

        if (current->getNext() == first) {
            delete first;
            first = current;
            first->setNext(NULL);
            listLength--;
            return true;
        }
        current = current->getNext();
    }
    return true;
}

bool RechnungsListe::deleteLast() {

    Rechnung* temp = last;
    last = last->getNext();
    listLength--;
    delete temp;
    return true;
}

But when I try to make a copy of my filled linked list I get an reading access violation and I don’t know why. Hopeful you cna help me.

That is my Main.cpp

std::srand(time(NULL));// einmaliger aufruf im gesamten Programm
    Rechnung* rechnung1 = new Rechnung();
    Rechnung* rechnung2 = new Rechnung();
    Rechnung* rechnung3 = new Rechnung();
    Rechnung* rechnung4 = new Rechnung();
    RechnungsListe liste;
    liste.pushFirst(*rechnung1);
    liste.pushFirst(*rechnung2);
    liste.pushLast(*rechnung3);
    liste.pushLast(*rechnung4);
    liste.print();


    std::cout << "nLÖSCHUNG VON LISTENELEMENTEN" << std::endl;
    liste.deleteLast();
    liste.deleteFirst();
    liste.print();

    RechnungsListe test(liste); //error

Source: Windows Questions C++

LEAVE A COMMENT