матричный процесс в с ++ - PullRequest
0 голосов
/ 27 октября 2019

Для моего промежуточного задания мне необходимо кодировать матрицу со всеми деталями (например, определить матрицу любого размера, добавить (и т. Д.) Число в матрицу, добавить (и т. Д.) Две матрицы вместе, транспонировать, определить, напечатать). .).

Я создал класс с именем Matrix, написал несколько конструкторов, функций и перегруженных операторов.

#include <iostream>
#include <string>
#include <ctime>
#include<fstream>
#include<cstdlib>
#include<iomanip>
#include <cmath>

using namespace std;

class Matrix {
private:
    int row;
    int column;
    int value;
    int** matrix;
public:
    Matrix(int ro, int col, int val);
    Matrix(int ro, int col, char type);
    ~Matrix();
    void print();
    void resize(int ro , int col);

    void operator=(const Matrix& other);
    Matrix operator+(int num)const;

};

Matrix::Matrix(int ro=10, int col=10, int val=0)
    :row(ro), column(col), value(val) 
    {
    if (row <= 0 || column <= 0) {
        cout << "invalid row or column value";
    }
    else{
        matrix = new int* [row];
        for (int i = 0; i < row; i++) {
            matrix[i] = new int[column];

        }
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < column; j++) {
                matrix[i][j] = value;
            }
        }
    }
}

Matrix::Matrix(int ro, int col, char type)
    :row(ro), column(col)
    {
    if (row <= 0 || column <= 0) {
        cout << "invalid row or column value";
    }
    else {
        matrix = new int* [row];
        for (int i = 0; i < row; i++) {
            matrix[i] = new int[column];
        }

        if (type == 'e'){

            for (int i = 0; i < row; i++) {
                for (int j = 0; j < column; j++) {
                    if (i == j) {
                        value = 1;
                        matrix[i][j] = value;
                    }
                    else {
                        value = 0;
                        matrix[i][j] = value;
                    }
                }
            }
        }
        srand(time(NULL));
        if (type == 'r') {
            for (int i = 0; i < row; i++) {
                for (int j = 0; j < column; j++) {
                    value = rand() % 256;
                    matrix[i][j] =value;
                }
            }
        }
    }
}



void Matrix::operator=(const Matrix& other) {

    this->resize(other.row, other.column);
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < column; j++) {
            matrix[i][j] = other.matrix[i][j]; // this line throw exception:Exception thrown at 0x00A7BCF2 in matrix.exe: 0xC0000005: Access violation reading location 0xDDDDDDDD.
        }
    }
}

Matrix Matrix::operator+(int num) const {

    Matrix model(row, column);
    for (int i = 0; i < model.row; i++) {
        for (int j = 0; j < model.column; j++) {
            model.matrix[i][j] = matrix[i][j] + num;
        }
    }
    return model;
}

void Matrix::print() {
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < column; j++) {
            cout<< setw(6) << matrix[i][j]<< " " ;
        }
        cout << endl;
    }
}

Matrix::~Matrix() {
    for (int i = 0; i < row; i++) {
        delete[] matrix[i];
    }
    delete[] matrix;
}


   void Matrix::resize(int ro, int col){
    int** copymatrix;
    copymatrix = matrix;
    matrix = new int* [ro];
    for (int i = 0; i < ro; i++) {
        matrix[i] = new int[col];
}
    for (int i = 0; i < ro; i++) {
        for (int j = 0; j < col; j++) {
            if (i >= row || j >= column) {
                matrix[i][j] = 0;
            }
            else {
                matrix[i][j] = copymatrix[i][j];
            }
        }
    }
    row = ro;
    column = col;
}

int main() {

    Matrix mat1(3, 6, 2);

    cout << endl;
    mat1 = mat1 + 5;
    mat1.print();


}

Я тоже пытался, но выдает ту же ошибку

Matrix Matrix::operator=(const Matrix& other) {

    Matrix model(other.row, other.column);
    for (int i = 0; i < model.row; i++) {
        for (int j = 0; j < model.column; j++) {
            model.matrix[i][j] = other.matrix[i][j]; //exception 
        }
    }
    return model;
}

У меня действительно проблемы с перегрузкой операторов. Когда я пишу в основной функции, когда я использую operator+ перегрузку, она возвращает матрицу, и после этого она переходит к operator= перегрузке, и возникает проблема, поскольку она возвращает матрицу и приходит к operator=, это дает мне ошибку Exception thrown at 0x00CEBCDB in matrix.exe: 0xC0000005: Access violation reading location 0xDDDDDDDD. Я думаю, что знаю почему, но я не знаю, как ее решить.

Этот код работает в CodeBlocks 17.12. Выдает ошибку в Visual Studio 2019 (v142).

Ответы [ 2 ]

0 голосов
/ 27 октября 2019
Matrix& Matrix::operator=(const Matrix& other) {
    if (this == &other) {
        return *this;
    }
    this->resize(other.row, other.column);
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < column; j++) {
            matrix[i][j] = other.matrix[i][j];
        }
    }
    return *this;
}

Matrix Matrix::operator+(int num) const {
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < column; j++) {
            this->matrix[i][j] += num;
        }
    }
    return *this;
}

Когда функция возвращает матрицу, завершив вызов области действия Destructor, и после того, как мы вызовем перегрузку оператора присваивания, она не сможет достичь члена этой матрицы, потому что она уже удалена Destructor, поэтому она вызывает исключение,Я написал это раньше, но это не сработало, пока я не понял, что мы должны поставить оператор (&) for (=), если мы хотим использовать эти операторы, перегружающие один за другим. так что теперь он работает хорошо

0 голосов
/ 27 октября 2019

Ваш оператор присваивания не назначает новую память для матрицы:

void Matrix::operator=(const Matrix& other) 
{
    this->resize(other.row, other.column);
    for (int i = 0; i < row; i++)
    for (int j = 0; j < column; j++) 
    {
        matrix[i][j] = other.matrix[i][j];
    }
}

Итак, после этого вы будете получать доступ к памяти через неинициализированный указатель.

Вам необходимо присвоениеоператоры, конструкторы, которые правильно распределяют память для ваших матриц. Вам тоже нужны соответствующие деструкторы. Посмотрите "правило 3".

...