Search code examples
c++classconstructordynamic-memory-allocationdefault-constructor

Can't fill dynamic array


I'm learning C++ now and I have some misunderstandings I've created 2d dynamic array, but I can't fill it I've got error in 44 line like: Access violation writing location 0xFDFDFDFD. This is my code:

#include <iostream>
#include <cmath>

using namespace std;

class Matrix
{
private:
    int row;
    int column;
    int** M;
public:
    Matrix();
    void setRow(int row) {
        this->row = row;
    }
    void setColumn(int column) {
        this->column = column;
    }
    int getRow() {
        return row;
    }
    int getColumn() {
        return column;
    }
    void setMat();
    void printMat();
    ~Matrix();
    
};

Matrix::Matrix() {
    M = new int* [row];
    for (int i = 0; i < row; i++) {
        M[i] = new int[column];
    }
    cout << "Constructor called";
}
//filling matrix
void Matrix::setMat() {
    for (int i = 0; i < row; i++) {
        cout << "Enter the first row";
        for (int j = 0; j < column; j++) {
            M[i][j]=j;
        }
    }
}
void Matrix::printMat() {
    for (int i = 0; i < row; i++) {
        cout << endl;
        for (int j = 0; j < column; j++) {
            cout<< M[i][j];
        }
    }
}
Matrix::~Matrix() {
    for (int i = 0; i < row; i++) {
        delete[] M[i];
    }
    delete[] M;
    cout << "constructor cancelled";
}
int main(){
    int numC, numR;
    Matrix a;
    cout << "Enter the number of column: ";
    cin>>numC;
    a.setColumn(numC);
    cout << "Enter the number of rows: ";
    cin >> numR;
    a.setRow(numR);
    int col = a.getRow();
    cout << col;
    a.setMat();
    a.printMat();
    
    
}

I think that the problem is with dynamic array, but I don't know how to fix it. I hope you'll help me. Also about column and row, I know about vector, but the task is to create row and column.


Solution

  • Your constructor is allocating the arrays before the row and column members have been initialized yet. You need to re-think your design.

    Try something more like this instead:

    #include <iostream>
    #include <cmath>
    
    using namespace std;
    
    class Matrix
    {
    private:
        int row;
        int column;
        int** M;
    
    public:
        Matrix(int row, int column);
        ~Matrix();
    
        int getRow() const {
            return row;
        }
    
        int getColumn() const {
            return column;
        }
    
        void setMat();
        void printMat() const;
    };
    
    Matrix::Matrix(int row, int column) : row(row), column(column) {
        M = new int* [row];
        for (int i = 0; i < row; i++) {
            M[i] = new int[column];
        }
        cout << "Constructor called";
    }
    
    Matrix::~Matrix() {
        for (int i = 0; i < row; i++) {
            delete[] M[i];
        }
        delete[] M;
        cout << "Destructor called";
    }
    
    void Matrix::setMat() {
        for (int i = 0; i < row; i++) {
            cout << "Enter the first row";
            for (int j = 0; j < column; j++) {
                M[i][j] = j;
            }
        }
    }
    
    void Matrix::printMat() const {
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < column; j++) {
                cout << M[i][j] << ' ';
            }
            cout << endl;
        }
        cout << endl;
    }
    
    int main(){
        int numR, numC;
        cout << "Enter the number of rows: ";
        cin >> numR;
        cout << "Enter the number of column: ";
        cin >> numC;
        Matrix a(numR, numC);
        cout << a.getRow();
        a.setMat();
        a.printMat();
        return 0;
    }
    

    If you really want to use separate setters for the row and column members, then try something more like this instead:

    #include <iostream>
    #include <cmath>
    
    using namespace std;
    
    class Matrix
    {
    private:
        int row;
        int column;
        int** M;
    
        void checkMat();
    
    public:
        Matrix();
        ~Matrix();
    
        void setRow(int row);
        void setColumn(int column);
    
        int getRow() const {
            return row;
        }
    
        int getColumn() const {
            return column;
        }
    
        void setMat();
        void printMat() const;
    };
    
    Matrix::Matrix() : row(0), column(0), M(NULL) {
        cout << "Constructor called";
    }
    
    Matrix::~Matrix() {
        for (int i = 0; i < row; i++) {
            delete[] M[i];
        }
        delete[] M;
        cout << "Destructor called";
    }
    
    void Matrix::setMat() {
        for (int i = 0; i < row; i++) {
            cout << "Enter the first row";
            for (int j = 0; j < column; j++) {
                M[i][j] = j;
            }
        }
    }
    
    void Matrix::setRow(int row) {
        this->row = row;
        checkMat();
    }
    
    void Matrix::setColumn(int column) {
        this->column = column;
        checkMat();
    }
    
    void Matrix::checkMat() {
        if ((!M) && (row > 0) && (column > 0)) {
            M = new int*[row];
            for (int i = 0; i < row; i++) {
                M[i] = new int[column];
            }
        }
    }
    
    void Matrix::printMat() const {
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < column; j++) {
                cout << M[i][j] << ' ';
            }
            cout << endl;
        }
        cout << endl;
    }
    
    int main(){
        int numR, numC;
        Matrix a;
        cout << "Enter the number of rows: ";
        cin >> numR;
        a.setRow(numR);
        cout << "Enter the number of column: ";
        cin >> numC;
        a.setColumn(numC);
        cout << a.getRow();
        a.setMat();
        a.printMat();
        return 0;
    }