Ошибка при выполнении кода: . Пожалуйста объясните в чем проблема

Вызвано исключение по адресу 0x00567276 в Study.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0xDDDDDDE1. в этой строке: if (ob.matrix[i][k] > ob.matrix[i][b]) { b = k; }

void sort(Matrix ob) {
            for (int i = 0; i < ob.n; i++) {
                for (int j = 0; j < ob.m - 1; j++) {
                    int b = j;
                    int a;
                    for (int k = j + 1; k < ob.m; k++) {
                        if (ob.matrix[i][k] > ob.matrix[i][b]) { b = k; }
                    }
                    a = ob.matrix[i][j];
                    ob.matrix[i][j] = ob.matrix[i][b];
                    ob.matrix[i][b] = a;
                }
            }
        }
#include <iostream>
#include <cstdlib>
#include <iomanip>
using namespace std;

class Matrix {
    int** matrix;
    int n, m;
public:
    Matrix() {
        cout << "Enter the sizes of matrix: ";
        cin >> n >> m;
        matrix = new int* [n];
        for (int i = 0; i < n; i++) {
            matrix[i] = new int[m];
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                matrix[i][j] = rand() % 20;
            }
        }
    }
    ~Matrix() {
        for (int i = 0; i < n; i++) {
            delete[] matrix[i];
        }
        delete[] matrix;

    }
    void show() {
        cout << setw(5);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                cout << matrix[i][j] << setw(5);
            }
            cout << endl;
        }
    }
    friend class Matrix1;
    friend void sum(Matrix ob, Matrix _ob);
};

void sum(Matrix ob, Matrix _ob) {
    cout << "The sum of two matrix is: " << endl << setw(5);
    for (int i = 0; i < ob.n; i++) {
        for (int j = 0; j < ob.m; j++) {
            cout << ob.matrix[i][j] << setw(5);
        }
        cout << "+" << setw(5);
        for (int j = 0; j < ob.m; j++) {
            cout << _ob.matrix[i][j] << setw(5);
        }
        cout << "=" << setw(5);
        for (int j = 0; j < ob.m; j++) {
            cout << ob.matrix[i][j] + _ob.matrix[i][j] << setw(5);
        }
        cout << endl;

    }

}

class Matrix1 {
public:
    void max(Matrix ob) {
        for (int i = 0; i < ob.n; i++) {
            int j;
            int a = ob.matrix[i][0];
            for (j = 1; j < ob.m; j++) {
                if(ob.matrix[i][j] > a) a = ob.matrix[i][j];
            }
            cout << "Maximum item of " << i << " line is " << a << endl;
        }
    }
    void sort(Matrix ob) {
        for (int i = 0; i < ob.n; i++) {
            for (int j = 0; j < ob.m - 1; j++) {
                int b = j;
                int a;
                for (int k = j + 1; k < ob.m; k++) {
                    if (ob.matrix[i][k] > ob.matrix[i][b]) { b = k; }
                }
                a = ob.matrix[i][j];
                ob.matrix[i][j] = ob.matrix[i][b];
                ob.matrix[i][b] = a;
            }
        }
    }
};

int main()
{

    Matrix ob1, _ob1;
    Matrix1 ob2;
    ob2.max(ob1);
    cout << endl;
    ob2.sort(ob1);
    cout << endl;
    ob1.show();
    cout << endl;
    sum(ob1, _ob1);
    cout << endl;
    return 0;
}

введите сюда описание изображения


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

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

В коде классическая ошибка - объект копируется, но при этом конструктор копирования не определен. А в классе есть голые указатели. И в результате объекты делят общий массив данных. И когда в одного класса отрабатывает деструктор, второй объект начинает указывать на битые данные.

Как пофиксить? написать конструктор копирования и оператор присваивания. Где то так

#include  <utility> // для swap

Matrix(const Matrix& ob) {
    n = ob.n;
    m = ob.m;
    matrix = new int* [n];
    for (int i = 0; i < n; i++) {
        matrix[i] = new int[m];
    }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            matrix[i][j] = ob.matrix[i][j];
        }
    }
}

// copy-swap idiom
Matrix& operator=(const Matrix& ob) {
    Matrix temp(ob);
    std::swap(this->n, temp.n);
    std::swap(this->m, temp.m);
    std::swap(this->matrix, temp.matrix);

    return *this;
}

Более простой способ - просто передавать все по ссылке на константу

То есть, вместо Matrix ob в списке параметров писать const Matrix& ob и все будет работать (даже быстрее). Работать будет, но кто знает, что завтра захочется дописать:) Но в любом случае, передавать по ссылке на константу - хороший ход.

А сам конструктор лучше переписать так

Matrix(int n, int m) : n(n), m(m){
    matrix = new int* [n];
    for (int i = 0; i < n; i++) {
        matrix[i] = new int[m];
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            matrix[i][j] = rand() % 20;
        }
    }
}

ну и вводить где то так

int n, m;
cout << "Введите размеры матрицы";
cin >> n >> m;
Matrix ob(n,m);
→ Ссылка