删除运算符[]或内存分配问题(?)

问题描述 投票:0回答:1

我一直在从事一个学校项目,它基本上是一个模拟图书馆的系统。我的问题是,每当一个客户预订一本书,然后我尝试删除他时,我都会收到错误:执行了断点指令(__debugbreak() 语句或类似的调用)。根据我所读到的内容,当我尝试读取超出范围的数组或删除已经不存在的内容时,就会发生这种情况,但即使有了这些知识,我也不知道如何解决这个问题。我的代码相当长,所以我将包括关键部分: 我的客户班

class Czytelnik {
private:

    class Osoba {
    private:
        friend Czytelnik;
        string imie;
        string nazwisko;
    public:
        Osoba(string x = "imie", string y = "nazwisko") {
            imie = x;
            nazwisko = y;
        }
        ~Osoba() {}
        friend ostream& operator<<(ostream& output, const Osoba& t)
        {
            output << "imie: " << t.imie << " nazwisko: " << t.nazwisko;
            return output;
        }
        friend istream& operator>>(istream& input, Osoba& t)
        {
            cout << "Podaj imie: ";
            input >> t.imie;
            cout << "Podaj nazwisko: ";
            input >> t.nazwisko;
            return input;
        }
        void print() {
            cout << this->imie << endl;
            cout << this->nazwisko << endl;
        }
        string getimie()
        {
            return imie;
        }
        string getnazwisko() {
            return nazwisko;
        }
        
        void setimie(string imie)
        {
            this->imie = imie;
        }
        void setnazwisko(string nazwisko)
        {
            this->nazwisko = nazwisko;
        }

    };
    Osoba osoba;
    float kara;
    Ksiazka** wypozyczona;
    int liczbaKsiazek; //liczba obecnie wypozyczonych ksiazek
public:
    Czytelnik(string a = "imie", string b = "nazwisko", float x = 0)
        : osoba(a, b), kara(x), liczbaKsiazek(0) {
        wypozyczona = new Ksiazka * [1];
    }

    Czytelnik(const Czytelnik& t)
        : osoba(t.osoba), kara(t.kara), liczbaKsiazek(t.liczbaKsiazek) {
        wypozyczona = new Ksiazka * [liczbaKsiazek];
        for (int i = 0; i < liczbaKsiazek; ++i) {
            wypozyczona[i] = new Ksiazka(*t.wypozyczona[i]);
        }
    }
    ~Czytelnik() {
        for (int i = 0; i < liczbaKsiazek; ++i) {
            delete wypozyczona[i];
        }
        delete[] wypozyczona;
    }
    Czytelnik& operator=(const Czytelnik& other) {//niezbedny aby wykonac pelna kopie tablicy z ksiazkami
        if (this != &other) {

            this->osoba = other.osoba;
            this->kara = other.kara;

            if (this->wypozyczona) {
                for (int i = 0; i < liczbaKsiazek; ++i) {
                    delete wypozyczona[i];
                }
                delete[] wypozyczona;
            }

            liczbaKsiazek = other.liczbaKsiazek;
            wypozyczona = new Ksiazka * [liczbaKsiazek];
            for (int i = 0; i < liczbaKsiazek; ++i) {
                wypozyczona[i] = new Ksiazka(*other.wypozyczona[i]);
            }
        }
        return *this;
    }
    Czytelnik(Czytelnik&& other) noexcept
    {
        this->osoba = move(other.osoba);
        this->kara = other.kara;
        this->wypozyczona = other.wypozyczona;
        this->liczbaKsiazek = other.liczbaKsiazek;
        other.wypozyczona = nullptr;
        other.kara = 0.0f;
        other.liczbaKsiazek = 0;
    }
    Ksiazka* operator[](int index) {
        if (index >= 0 && index < liczbaKsiazek) {
            return wypozyczona[index];
        }
        else {
            return nullptr;
        }
    }

    Czytelnik& operator=(Czytelnik&& other) noexcept {
        if (this != &other) {
            this->osoba = move(other.osoba);
            this->kara = other.kara;

            delete[] this->wypozyczona;
            this->wypozyczona = other.wypozyczona;

            other.wypozyczona = nullptr;
            other.kara = 0.0f;
        }
        return *this;
    }
    const Ksiazka* operator[](int index) const {
        if (index >= 0 && index < liczbaKsiazek) {
            return wypozyczona[index];
        }
        else {
            return nullptr;
        }
    }
    friend ostream& operator<<(ostream& output, const Czytelnik& t)
    {
        output << t.osoba << " kara: " << t.kara << " wypozyczone: ";
        bool firstBook = true;

        for (int i = 0; i < t.liczbaKsiazek; ++i)
        {
            if (!t.wypozyczona[i]->gettytul().empty())
            {
                if (!firstBook)
                    output << ", ";
                output << t.wypozyczona[i]->gettytul() << ", " << t.wypozyczona[i]->getautor();
                firstBook = false;
            }
        }
        output << endl;
        return output;
    }
    friend istream& operator>>(istream& input, Czytelnik& t)
    {
        input >> t.osoba;
        return input;
    }
    void setimie(string imie) {
        this->osoba.setimie(imie);
    }
    void setnazwisko(string nazwisko) {
        this->osoba.setnazwisko(nazwisko);
    }
    void setkara(float kara) {
        this->kara = kara;
    }
    void setliczbaKsiazek(int liczba) {
        this->liczbaKsiazek = liczba;
    }
    string getimie() {
        return this->osoba.getimie();
    }
    string getnazwisko() {
        return this->osoba.getnazwisko();
    }
    float getkara() {
        return kara;
    }
    int getliczbaKsiazek() {
        return liczbaKsiazek;
    }
    Ksiazka** getwypozyczona() {
        return wypozyczona;
    }
    void print()
    {
        cout << "imie: " << this->osoba.getimie() << " nazwisko: " << this->osoba.getnazwisko() << " kara: " << this->kara << " wypozyczone: ";
        bool firstBook = true;

        for (int i = 0; i < liczbaKsiazek; ++i)
        {
            if (!this->wypozyczona[i]->gettytul().empty())
            {
                if (!firstBook)
                    cout << ", ";
                cout << this->wypozyczona[i]->gettytul() << ", " << this->wypozyczona[i]->getautor();
                firstBook = false;
            }
        }
        cout << endl;
    }

    void wypozycz(Ksiazka* book) {
        // If wypozyczona array is not initialized, initialize it
        if (!wypozyczona) {
            wypozyczona = new Ksiazka * [1]; // Start with one slot
        }

        // Reallocate memory for wypozyczona array to accommodate the new book
        Ksiazka** temp = new Ksiazka * [liczbaKsiazek + 1];
        for (int i = 0; i < liczbaKsiazek; ++i) {
            temp[i] = wypozyczona[i];
        }
        temp[liczbaKsiazek] = book;

        // Clean up old array and update wypozyczona
        delete[] wypozyczona;
        wypozyczona = temp;
        liczbaKsiazek++;

        cout << "Book '" << book->gettytul() << "' borrowed successfully by " << getimie() << " " << getnazwisko() << "." << endl;
    }

};

初始化:

void zainicjuj(Czytelnik*& czytelnicy, int size)
{
    static random_device seed;
    static default_random_engine dfe(seed());
    uniform_int_distribution<int> distribution(0, 9);
    string_view imiona[10] = { "Zuzia", "Marek", "Tadek", "Oliwia", "Gracjan", "Mateusz", "Ignacy", "Leosia", "Przemek", "Joanna" };
    string_view nazwiska[10] = { "Kulas", "Kaczmarek", "Leja", "Kmiecik", "Marciniak", "Kononowicz", "Koziol", "Olekszyk", "Narkiewicz", "Pietruszka" };
    string imionav[10], nazwiskav[10];
    for (int i = 0; i < 10; i++)
    {
        imionav[i] = imiona[i];
        nazwiskav[i] = nazwiska[i];
    }
    for (int i = 0; i < size; i++)
    {
        int random = distribution(dfe);
        int random2 = distribution(dfe);
        // Create a new Czytelnik object with random name and surname
        czytelnicy[i].setimie(imionav[random]);
        czytelnicy[i].setnazwisko(nazwiskav[random2]);
        czytelnicy[i].setkara(0.0f); // Set initial value for kara
        czytelnicy[i].setliczbaKsiazek(0); // Set initial value for liczbaKsiazek
        czytelnicy[i].getwypozyczona()[0] = new Ksiazka();
    }
}

分配书籍功能:

void wypozycz(Czytelnik*& czytelnicy, int ileCzytelnikow, Ksiazka*& ksiazki, int ileKsiazek) {
    string imie, nazwisko, tytul;
    bool znalezionoCzytelnika = false;
    bool znalezionoKsiazke = false;

    cout << "Podaj imie czytelnika: ";
    cin >> imie;
    cout << "Podaj nazwisko czytelnika: ";
    cin >> nazwisko;
    cout << "Podaj tytul ksiazki: ";
    cin >> tytul;

    for (int i = 0; i < ileCzytelnikow; ++i) {
        if (czytelnicy[i].getimie() == imie && czytelnicy[i].getnazwisko() == nazwisko) {
            znalezionoCzytelnika = true; //znaleziono czytelnika

            for (int j = 0; j < ileKsiazek; ++j) {
                if (ksiazki[j].gettytul() == tytul && ksiazki[j].getdostepna()) {
                    znalezionoKsiazke = true; //znaleziono ksiazke

                    czytelnicy[i].wypozycz(&ksiazki[j]);
                    ksiazki[j].setdostepna(false);
                    // czytelnik nie ma miejsca na wiecej ksiazek
                    cout << "Czytelnikowi brakuje miejsca na wypozyczenie kolejnej ksiazki." << endl;
                    return;
                }
            }
            // ksiazki nie ma / jest juz wypozyczona
            if (!znalezionoKsiazke) {
                cout << "Ksiazka o podanym tytule nie istnieje lub jest juz wypozyczona." << endl;
                return;
            }
        }
    }
    // czytelnika nie ma
    if (!znalezionoCzytelnika) {
        cout << "Nie znaleziono czytelnika o podanym imieniu i nazwisku." << endl;
    }
}

以及删除客户端功能:

void zwolnij(Czytelnik*& czytelnicy, int& size) {
    string nazwisko;
    int id = -1;
    cout << "Podaj nazwisko: " << endl;
    cin >> nazwisko;
    for (int i = 0; i < size; i++)
    {
        if (czytelnicy[i].getnazwisko() == nazwisko) {
            id = i;
            break;
        }
    }
    if (id != -1)
    {
        for (int i = 0; i < czytelnicy[id].getliczbaKsiazek(); ++i) {
            delete czytelnicy[id].getwypozyczona()[i];
        }
        // Delete the wypozyczona array
        delete[] czytelnicy[id].getwypozyczona();
        Czytelnik* temp;
        stworz(temp, size - 1);
        int j = 0;
        for (int i = 0; i < size; i++)
        {
            if (i != id) {
                temp[j++] = czytelnicy[i];
            }
        }

        delete[] czytelnicy;
        czytelnicy = temp;
        --size;
        cout << "Usunieto czytelnika o nazwisku: " << nazwisko << endl;

    }
    else {
        cout << "Nie znaleziono osoby o podanym nazwisku" << endl;
    }
}

我知道有很多要求,特别是因为代码是波兰语的(因为它是一个学校项目),但我已经被这个问题困扰很长时间了,非常感谢任何帮助!另请记住,我必须在原始指针上完成所有操作,并且不能使用向量。

我尝试调试我的代码,并尝试了不同的方法(例如处理对象数组而不是指针数组)。聊天GPT似乎也不知道发生了什么。 另外我忘了提及,当我尝试删除没有任何书籍的用户时,它工作得很好。

c++ memory delete-operator
1个回答
0
投票

确保删除 Czytelnik 对象后您不会访问该对象的任何成员函数或变量。 确保所有循环和索引都正确限制,以避免访问内存越界。 确认您没有多次删除同一内存位置。 考虑使用调试器工具单步执行代码并确定发生错误的确切位置。

© www.soinside.com 2019 - 2024. All rights reserved.