Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overload operator matrix, access violation reading

I just want to overload operator with matrix, but I have a problem when I use it. The program can get through operator function but have a problem with this line tong = mt1+mt2 the same problem with line tich = mt1*mt2. I can't understand why. Please help me. Thanks 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();
}
like image 209
Ruồi Trâu Avatar asked Jun 04 '26 12:06

Ruồi Trâu


1 Answers

The rule of three (aka law of the big three, etc.) says that if your class implements any one of a copy constructor, copy assignment operator, or destructor, you nearly always need to implement all three of them. Typically (as in this case) you realize you need the dtor to free the memory you've allocated. In that case, you nearly always need a copy constructor and a copy assignment operator.

The rule of 5 is an update of that for C++11, where you add move assignment and move construction along with the previous three.

The rule of zero says you should usually avoid all of the above, and use some existing class to actually manage the memory, instead of trying to do it on your own. 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, a copy constructor would probably look at least roughly 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];
    }
}

A move ctor would 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'll need to do roughly the same for move assignment (well, both move-assignment and move construction are optional, but strongly recommended if you're going to implement something like this).

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

like image 127
Jerry Coffin Avatar answered Jun 06 '26 07:06

Jerry Coffin