Вызвано необработанное исключение: нарушение доступа для чтения. 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 шт):
Я не понимаю, как оно у вас вообще скомпилировалось, но допустим, что вы как-то заставили компилятор...
У вас две матрицы 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("Неверные размеры матриц"));