Вызвано необработанное исключение: нарушение доступа для чтения. this->**arr** было 0x5500550

Я написал класс матрицы на плюсах. Все работает отлично, кроме оператора умножения. Когда начинается умножение, выдает ошибку в деструкторе : Ошибка

Возникает вопрос: как это произошло и как это исправить?

//MAIN
#include <locale.h>
#include <iostream>

#include "Matrix.h"

using namespace std;

int main()
{
    setlocale(LC_ALL, "rus");
    int N = 2, M = 3;
    Matrix A(N, M);
    Matrix B(N, M);
    Matrix C(N, M);

    int i, j;
    for (i = 0; i < N; i++)
        for (j = 0; j < M; j++)
        {
            C.SetArr(i, j, rand() % 100);
            B.SetArr(i, j, rand() % 100);
            A.SetArr(i, j, rand() % 100);
        }
    A.Print("A");
    A.Input(N, M);
    A.Print("A");
    B.Print("B");
    C.Print("C");


    cout << " A+B \n" << (A + B) << endl;
    cout << " A-B \n" << (A - B) << endl;

    cout << " A*B \n" << (A * B) << endl;

    cout << "Сумма элементов 0 строки " << A.SummN(0) << endl;
    cout << "Сумма элементов 1 столбца " << A.SummM(1) << endl;
}



//HEADER
#ifndef MATRIX_H
#define MATRIX_H
#include <iostream>
#include <string>
using namespace std;

class Matrix
{
public:
    Matrix();
    Matrix(int _n, int _m);
    Matrix(const Matrix& _arr);

    double GetArr(int i, int j);
    void SetArr(int i, int j, double value);
    void Print(const char* ObjName);
    void Input(int _n,int _m);


    Matrix operator=(const Matrix& _arr);
    Matrix operator+(const Matrix& arr);
    Matrix operator-(const Matrix& arr);
    Matrix operator*(const Matrix& arg);

    int SummN(int arg);
    int SummM(int arg);
    friend std::ostream& operator<<(std::ostream& os, const Matrix& arr);


    virtual ~Matrix();
private:
    int n;
    int m;
    double** arr = nullptr;

};
#endif


//METHODS
#include <iostream>

#include "Matrix.h"
using namespace std;


Matrix::Matrix() // Конструктор по умолчанию
{
    n = 0;
    m = 0;
    arr = nullptr;
}


Matrix::Matrix(int _n, int _m)//Конструктор с параметрами
{

    n = _n;
    m = _m;
    arr = new double* [n];
    
    for (int i = 0; i < n; ++i)
    {
        arr[i] = new double[m] {0};
        
    }

}


Matrix::Matrix(const Matrix& _arr)
{
    n = _arr.n;
    m = _arr.m;

    arr = new double* [n];

    for (int i = 0; i < n; ++i)
    {
        arr[i] = new double[m] {0};

    }

    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            arr[i][j] = _arr.arr[i][j];
    
}


double Matrix::GetArr(int i, int j)
{
    if ((n > 0) && (m > 0))
        return arr[i][j];
    else
        return 0;
}


void Matrix::SetArr(int i, int j, double value)
{
    if ((i < 0) || (i >= n))
        return;
    if ((j < 0) || (j >= m))
        return;
    arr[i][j] = value;
}


void Matrix::Print(const char* Name)
{
    cout << "Матрица: " << Name << endl;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
            cout << arr[i][j] << "\t";
        cout << endl;
    }
    cout << "---------------------" << endl << endl;
}


Matrix Matrix::operator=(const Matrix& _arr)
{
    if (m > 0)
    {

        for (int i = 0; i < n; i++)
            delete[] arr[i];
    }

    if (n > 0)
    {
        delete[] arr;
    }

    n = _arr.n;
    m = _arr.m;
    


    arr = new double* [n];
    for (int i = 0; i < n; ++i)
        arr[i] = new double[m] {0};



    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            arr[i][j] = _arr.arr[i][j];
    return *this;
}


Matrix Matrix::operator+(const Matrix& arr) 
{
    if (n == arr.n && m == arr.m) 
    { 
        Matrix result(*this); // Копируем данные из *this в result (конструктор копирования)
        for (int i = 0; i < n; ++i) 
        {
            for (int j = 0; j < m; ++j)
            {
                result.arr[i][j] += arr.arr[i][j]; // В result копия данных this складывается с данными arg
            }
        }
        return result;
    }
}


Matrix Matrix::operator-(const Matrix& arr)
{
    if (n == arr.n && m == arr.m)
    {
        Matrix result(*this); // Копируем данные из *this в result (конструктор копирования)
        for (int i = 0; i < n; ++i)
        {
            for (int j = 0; j < m; ++j)
            {
                result.arr[i][j] -= arr.arr[i][j]; // В result копия данных this складывается с данными arg
            }
        }
        return result;
    }
}


Matrix Matrix::operator*(const Matrix& arg)
{

    if (m == arg.n)
    { // Если число стб. матрицы this совпадает с числом стр. матрицы arg, то умножение возможно
        Matrix result(this->n, arg.m); // Конструктор по размерам
        for (int i = 0; i < n; ++i) 
        {
            for (int j = 0; j < arg.m; ++j) 
            {
                for (int k = 0; k < m; ++k) 
                {
                
                    result.arr[i][j] += (arr[i][k]) * (arg.arr[k][j]);
                }
            }
        }
        return result;
    }
}



void Matrix::Input(int _n,int _m)
{
    n = _n;
    m = _m;

    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            cin >> arr[i][j];
}


int Matrix::SummN(int arg)
{
    int Summ = 0;
    for (int i = 0; i < m; i++)
        Summ += arr[arg][i];
    return Summ;
}


int Matrix::SummM(int arg)
{
    int Summ = 0;
    for (int i = 0; i < n; i++)
        Summ += arr[i][arg];

    return Summ;
}


ostream& operator<<(ostream& os, const Matrix& arr) {
    for (int i = 0; i < arr.n; ++i) 
    {
        os << arr.arr[i][0];
        for (int j = 1; j < arr.m; ++j) 
        {
            os << ' ' << arr.arr[i][j];
        }
        os << '\n';
    }
    return os;
}


Matrix::~Matrix()//Деструктор
{
    for (int i = 0; i < n; ++i) 
    {
        delete[] arr[i];
    }
    delete[] arr;
}

Ответы (1 шт):

Автор решения: Harry

Я не понимаю, как оно у вас вообще скомпилировалось, но допустим, что вы как-то заставили компилятор...

У вас две матрицы 2x3:

Matrix A(N, M);
Matrix B(N, M);

И как вы их собираетесь множить? Если для умножения количество столбцов в первой должно быть равно количеству строк во второй?

Смотрим ваше умножение (выбрасываю не относящийся к делу код):

Matrix Matrix::operator*(const Matrix& arg)
{

    if (m == arg.n)
    { // Если число стб. матрицы this совпадает с числом 
      // стр. матрицы arg, то умножение возможно
        ...
        return result;
    }
}

У вас m != arg.n — так что вы возвращаете? (Это именно то место, на которое компилятор должен был ругаться насквозь нецензурно.) Какую матрицу?

Да никакую! "Черт-те что и сбоку бантик", как говорится. Для этого не пойми чего вы потом вызываете деструктор. Вот и все. Он пытается удалять память по какому-то непонятному указателю, по которому никогда не была выделенная память!

Учите исключения — здесь бы было неплохо

    if (m != arg.n) throw(runtime_error("Неверные размеры матриц"));
→ Ссылка