适当的内存释放

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

如果我有:

class Foo{
Bar** bars = new Bar*10;
};
class Bar{
string temp;
};

如果我有一系列 Foos:

Foo* foos = new Foo[5];

如果我想删除数组,应该像这样:

for(int i = 0; i < 5; i++)
{
   for(int j = 0; j < 10; j++)
   {
      delete foos[i].bars[j];
   }
   delete[] foos[].bars;
}
delete[] foos;

? 每次我尝试删除时都会抛出异常

还尝试只删除每个对象内的数组,而不删除数组的对象,但也失败了。 完整代码:

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include <random>
int MAX_BOOKS = 10;
using namespace std;
class Book {
private:
    string title, author;
    mutable bool canBook;
public:
    Book(string x = "", string y = "", bool z = false) : title(x), author(y), canBook(z) {}

    ~Book() {}

    Book(const Book& t)
    {
        this->title = t.title;
        this->author = t.author;
        this->canBook = t.canBook;
    }
    
    void print() {
        string available;
        cout << "title: " << this->title;
        cout << " author: " << this->author;
        if (this->canBook == true)
        {
            available = "yes";
        }
        else
        {
            available = "no";
        }
        cout << " canBook: " << available << endl;
    }

    string gettitle()
    {
        return title;
    }
    string getauthor() {
        return author;
    }
    bool getcanBook() {
        return canBook;
    }
    void settitle(string title)
    {
        this->title = title;
    }
    void setauthor(string author)
    {
        this->author = author;
    }
    void setcanBook(bool canBook) {
        this->canBook = canBook;
    }
};

class Reader {
private:
    class Person {
    private:
        friend Reader;
        string name, surname;
    public:
        Person(string x = "name", string y = "surname") {
            name = x;
            surname = y;
        }
        ~Person() {}
        string getname()
        {
            return name;
        }
        string getsurname() {
            return surname;
        }

        void setname(string name)
        {
            this->name = name;
        }
        void setsurname(string surname)
        {
            this->surname = surname;
        }
    };
    Person Person;
    float penalty;
    Book** booked = new Book*[MAX_BOOKS]; //books
    int bookedNum; //currently booked
public:
    //constructor
    Reader(string a = "name", string b = "surname", float x = 0)
        : Person(a, b), penalty(x), bookedNum(0) {
        for (int i = 0; i < MAX_BOOKS; ++i)
        {
            booked[i] = new Book();
        }
        //booked = new Book * [MAX_BOOKS];
    }
    // copy-constructor
    Reader(const Reader& t)
        : Person(t.Person), penalty(t.penalty), bookedNum(t.bookedNum) {
        booked = new Book * [bookedNum];
        for (int i = 0; i < bookedNum; ++i) {
            booked[i] = new Book(*t.booked[i]);
        }
    }
    //destructor
    ~Reader() { 
        for (int i = 0; i < MAX_BOOKS; ++i) {
            delete booked[i];
        }
        delete[] booked;
    }
    //copy-swap
    Reader& operator=(const Reader& other){ 
        Reader temp(other); 
        std::swap(temp.Person, Person); 
        std::swap(temp.penalty, penalty); 
        std::swap(temp.booked, booked); 
        std::swap(temp.bookedNum, bookedNum); 
        return *this;
    }

    Reader& operator=(Reader&& other) noexcept
    {
        if (this != &other)
        {
            this->Person = move(other.Person);
            this->penalty = other.penalty;
            this->bookedNum = other.bookedNum;
            delete[] this->booked;
            this->booked = other.booked;
            other.booked = nullptr;
            other.penalty = 0.0f;
            other.bookedNum = 0;
        }
        return *this;
    }
    void setname(string name) {
        this->Person.setname(name);
    }
    void setsurname(string surname) {
        this->Person.setsurname(surname);
    }
    void setpenalty(float penalty) {
        this->penalty = penalty;
    }
    void setliczbaKsiazek(int liczba) {
        this->bookedNum = liczba;
    }
    string getname() {
        return this->Person.getname();
    }
    string getsurname() {
        return this->Person.getsurname();
    }
    float getpenalty() {
        return penalty;
    }
    int getliczbaKsiazek() {
        return bookedNum;
    }
    Book** getwypozyczona() {
        return booked;
    }
    void print()
    {
        cout << "name: " << this->Person.getname() << " surname: " << this->Person.getsurname() << " penalty: " << this->penalty << " booked: ";
        bool firstBook = true;

        for (int i = 0; i < bookedNum; ++i)
        {
            if (!this->booked[i]->gettitle().empty())
            {
                if (!firstBook)
                    cout << ", ";
                cout << this->booked[i]->gettitle() << ", " << this->booked[i]->getauthor();
                firstBook = false;
            }
        }
        cout << endl;
    }

};

void stworz(Reader*& readers, int size)
{
    readers = new Reader[size];
}

void stworz(Book*& books, int size)
{
    books = new Book[size];
}

void zainicjuj(Book*& books, int size)
{
    static random_device seed;
    static default_random_engine dfe(seed());
    uniform_int_distribution<int> distribution(0, 9);
    string_view tytuly[10] = { "Diuna", "Wesele", "Obcy", "Gra", "Pomnik", "Tadeusz", "Zbrodnia", "Lalka", "Basnie", "Wiedzmin" };
    string_view autorzy[10] = { "Mickiewicz", "Krasicki", "Slowacki", "Sienkiewicz", "Zajdel", "Dostojewski", "Prus", "Wyspianski", "Sapkowski", "Herbert" };
    string tytulyv[10];
    string autorzyv[10];
    for (int i = 0; i < 10; i++)
    {
        tytulyv[i] = tytuly[i];
        autorzyv[i] = autorzy[i];
    }

    for (int i = 0; i < size; i++)
    {
        int random = distribution(dfe);
        int random2 = distribution(dfe);
        books[i].settitle(tytulyv[random]);
        books[i].setauthor(autorzyv[random2]);
        books[i].setcanBook(true);
    }
}

void pokaz(Reader*& readers, int size) {
    for (int i = 0; i < size; i++)
    {
        readers[i].print();
    }
}

void pokaz(Book*& books, int size) {
    for (int i = 0; i < size; i++)
    {
        books[i].print();
    }
}

void zwolnij(Reader*& readers, int& size)
{
    string surname;
    int id = -1;
    cout << "Type in surname: " << endl;
    cin >> surname;
    for (int i = 0; i < size; i++)
    {
        if (readers[i].getsurname() == surname) {
            id = i;
            break;
        }
    }
    if (id != -1)
    {
        Reader* temp = new Reader[size-1];
        int j = 0;
        for (int i = 0; i < size; i++)
        {
            if (i != id)
            {
                temp[j++] = readers[i];
            }
        }
        for (int i = 0; i < size; i++)
        {
            delete[] readers[i].getwypozyczona();
        }
        delete[] readers;
        readers = temp;
        --size;
        cout << "Usunieto czytelnika" << endl;
    }
    else {
        cout << "Nie znaleziono czytelnika" << endl;
    }
}

int main()
{
    int ileCzytelnikow = 5;
    Reader* readers = new Reader[ileCzytelnikow];
    readers[0] = Reader("John", "Doe", 0); // Example data
    readers[1] = Reader("Jane", "Smith", 0); // Example data
    readers[2] = Reader("Alice", "Johnson", 0); // Example data
    readers[3] = Reader("Bob", "Brown", 0); // Example data
    readers[4] = Reader("Carol", "Davis", 0); // Example data

   
    int ileKsiazek = 5;
    Book* books = new Book[ileKsiazek];
    

    int x = 0;

    do {
        cout << "Pick an action: \n";
        cout << "1. Show readers \n";
        cout << "2. Show books \n";
        cout << "3. Delete a Reader \n";
        //cout << "4. Check out a book \n";
        cout << "5. End \n";
        cin >> x;

        switch (x) {
        case 1:
            pokaz(readers, ileCzytelnikow);
            break;
        case 2:
            pokaz(books, ileKsiazek);
            break;
        case 3:
            zwolnij(readers, ileCzytelnikow);
            break;
        case 4:
            //borrow(readers, ile, books, ilosc);
            break;
        case 5:
            return 0;
        default:
            cout << "Invalid prompt" << endl;
            break;
        }
    } while (x != 5);
    delete[] readers;
    delete[] books;
    return 0;
}

我相信这是我现在可以实现的最简单的版本,但我仍然无法识别导致异常的原因。

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

这就是你想要做的吗?您没有实例化二维数组的第二个维度。

class Foo{
public:
    Bar ** bars;
    
    Foo()
    {
        bars = new Bar*[10];
        for(int i = 0; i < 10; ++i)
            bars[i] = new Bar[10];
    }
    

};


void DoDelete()
{
    Foo* foos = new Foo[5];
        
    for(int i = 0; i < 5; i++)
    {
       for(int j = 0; j < 10; j++)
       {
          delete [] foos[i].bars[j];
       }
       delete [] foos[i].bars;
    }
    delete[] foos;

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