Overload operator matrix, read access violation

I just want to overload an operator with a matrix, but I have a problem when I use it. The program can go through the operator function, but the problem with this line tong = mt1+mt2

is the same problem with the line tich = mt1*mt2

. I do not understand why. Please help me. Thank you so much for your help.

#include <stdio.h>
#include <conio.h>
#include <iostream>

using namespace std;

class MT{
private:
int row;
int col;
int **matrix;
public:
MT(){
    row = 0;
    col = 0;
    matrix = NULL;
}
MT(int row1, int col1){
    row = row1;
    col = col1;
    matrix = new int *[row];
    for (int i = 0; i<row; i++)
        matrix[i] = new int[col];
}
~MT(){
    for (int i = 0; i<row; i++)
        delete []matrix[i];
    delete []matrix;
}
friend ostream& operator<< (ostream &os,const MT &mt){
    for (int i = 0; i<mt.row; i++){
        for (int j = 0; j<mt.col; j++)
            cout << mt.matrix[i][j]<<"   ";
        cout <<endl;
    }
    return os;
}
friend istream& operator>> (istream &is,MT &mt){
    int row1, col1;
    cout <<"\n Nhap so row ma tran:   "; fflush(stdin); cin >> row1;
    cout <<"\n Nhap so col ma tran:    "; fflush(stdin); cin >> col1;
    mt.row = row1;
    mt.col = col1;
    mt.matrix = new int *[row1];
    for (int i = 0; i<row1; i++)
        mt.matrix[i] = new int[col1];
    for (int i = 0; i < row1; i++)
        for (int j = 0; j< col1; j++)
            is >> mt.matrix[i][j];
    return is;
}
MT operator+(MT &mt){
    MT temp(mt.row,mt.col);
    if ((this->row != mt.row) || (this->col != mt.col)){
        cout <<"\n Khong the thuc hien phep cong!";
        return temp;
    }
    else{
        for (int i = 0; i < row; i++)
            for (int j = 0; j < col; j++)
                temp.matrix[i][j] = this->matrix[i][j] + mt.matrix[i][j];
        return temp;
    }
}
MT operator-(MT &mt){
    MT temp(mt.row,mt.col);
    if ((this->row != mt.row) || (this->col != mt.col)){
        cout <<"\n Khong the thuc hien phep tru!";
        return temp;
    }
    else{
        for (int i = 0; i < row; i++)
            for (int j = 0; j < col; j++)
                temp.matrix[i][j] = this->matrix[i][j] - mt.matrix[i][j];
        return temp;
    }
}
MT operator*(MT &mt){
    MT temp(this->row, mt.col);
    if (this->row != mt.col){
        cout <<"\n Khong the thuc hien phep nhan.";
        return temp;
    }
    else{
        for (int i = 0; i < this->row; i++)
            for (int j = 0; j < mt.col; j++)
            {
                temp.matrix[i][j] = 0;
                for (int k = 0; k<this->row; i++)
                    temp.matrix[i][j] += this->matrix[i][k]*mt.matrix[k][j];
            }
            return temp;
    }
}
MT operator=(MT &mt){
    row = mt.row;
    col = mt.col;
    this->matrix = new int *[row];
    for (int i=0; i<row; i++)
        this->matrix[i] = new int[col];
    for (int i =0; i<row; i++)
        for (int j = 0; j<col; j++)
            this->matrix[i][j] = mt.matrix[i][j];
    return mt;
}
};

void main()
{
MT mt1,mt2,tong,tich;
cin>>mt1;
cin>>mt2;
tong = mt1+mt2;
cout <<tong;
tich = mt1*mt2;
cout <<tich;
_getch();
}

      

+3


source to share


1 answer


The rule of three (usually the big three, etc.) says that if your class implements any of the copy constructors, copy assignment operator, or destructor, you almost always need to implement all three of them. Usually (as in this case) you realize that you need a dtor to free the allocated memory. In this case, you almost always need a copy constructor and a copy assignment operator.

Rule 5 is an update for C ++ 11 where you add a move assignment and move the construct along with the previous three.

The rule of zero says that you should generally avoid all of the above and use some existing class to actually manage memory, instead of trying to do it yourself. The obvious options are std::shared_ptr

and std::unique_ptr

, or using an existing container such as std::vector

or std::deque

.

In your case, the copy constructor would probably look something like this:

MT(MT const &r){
    row = r.row;
    col = r.col;
    matrix = new int *[row];
    for (int i = 0; i<row; i++) {
        matrix[i] = new int[col];
        for (int j=0; j<col; j++)
            matrix[i][j] = r.matrix[i][j];
    }
}

      



Moving the ctor will look something like this:

MT (MT &&r) {
     row=r.row;
     col=r.col;
     matrix = r.matrix;
     r.row=0;
     r.col=0;
     r.matrix = nullptr;
}

      

Then you need to do roughly the same thing for the move assignment (well, both the move and the move of the structure are optional, but highly recommended if you are going to implement something like this).

Also note that your copy assignment operator should normally take its operand by reference and return a non-const reference (which it should almost always be return *this;

).

+2


source







All Articles