Страницы

Поиск по вопросам

суббота, 11 января 2020 г.

Проблема с освобождением памяти в деструктор c++

#cpp #динамические_массивы


Пишу свой класс математических матриц, храню все в double**. Все работало нормально,
пока не решил заняться деструктором. Теперь при вызове какого либо оператора или функции
мне вылетает исключение: "Ошибка доступа к чтению". Я уже понял из-за чего она вылетает. 
Вот мой типичный код:

Matrix Matrix::operator+ (Matrix M)
{
    Matrix Temp(Rows, Columns);
    for (unsigned i(0); i < Rows; i++)
        for (unsigned j(0); j < Columns; j++)
            Temp[i][j] = M[i][j] + Element[i][j];
    return Temp;
}


Когда он возвращает Temp, он уничтожает все элементы, и Temp не доходит до конца.
Вот деструктор:

Matrix::~Matrix()
{
    for (unsigned i(0); i < Rows; i++)
        delete[] Element[i];
    delete[] Element;
}


Подскажите как мне правильно сделать деструктор.
    


Ответы

Ответ 1



Вы забыли написать реализовать правильный конструктор копирования, так как конструктор копирования по умолчанию просто копирует указатели. И когда у вас будет два объекта, которые ссылаются на одну и ту же область памяти и у них обоих вызовется деструктор, то он попытается дважды освободить одну и ту же память. Пример кода по правилу copy-and-swap idiom: class Matrix { public: Matrix(size_t rows = 0, size_t columns = 0) : rows_(rows), columns_(columns), pMat(rows || columns ? new double[rows * columns] : nullptr) {} Matrix(Matrix const & obj) : rows_(obj.rows_), columns_(obj.columns_), pMat(obj.rows_ || obj.columns_ ? new double[obj.rows_ * obj.columns_] : nullptr) { std::copy(obj.pMat, obj.pMat + obj.rows_ * obj.columns_, pMat); } Matrix(Matrix&& obj) noexcept : Matrix() { swap(*this, obj); } ~Matrix() { delete[] pMat; } friend void swap(Matrix& first, Matrix& second) { using std::swap; swap(first.rows_, second.rows_); swap(first.columns_, second.columns_); swap(first.pMat, second.pMat); } Matrix const & operator= (Matrix obj) { swap(*this, obj); return *this; } private: double** pMat; size_t rows_; size_t columns_; };

Комментариев нет:

Отправить комментарий