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.
CodePudding user response:
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;
}
CodePudding user response:
This declaration
Matrix a;
where there is used the default constructor leaves data members row
and column
uninitialized. So at least the constructor invokes undefined behavior where the uninitialized data members are used to allocate dynamically memory.
Matrix::Matrix() {
M = new int* [row];
for (int i = 0; i < row; i ) {
M[i] = new int[column];
}
cout << "Constructor called";
}.
You need to use either some default values for the data members row and column or redeclare the constructor with two parameters that will set values for the data members.
Also member functions setRow
and setColumn
makes the state of an object inconsistent because the dynamically allocated memory of the object is not reallocated according to new values of the data members row
and column
.