I have this C++ class Matrix (see code snipet below).
In my randomize method, I set all the values of matr(matr is a 2x2 matrix).
When i call print_matrix it is duplicating elements (1,0) and (1,1) and printing them both twice, as well a not printing (0,0), or (0,1).
What am I doing incorrectly?
See the output below.
class Matrix {
public:
int rows;
int cols;
double rnd;
double* matr;
Matrix(int a, int b) {
printf(" vals %d %d \n", a, b);
rows = a;
cols = b;
matr = new double[a, b];
//this->print_matrix();
//clear_matrix();
//this->print_matrix();
//this->randomize();
//this->print_matrix();
}
double &at(int pos1, int pos2) {
return matr[pos1, pos2];
};
void setPos(int pos1, int pos2, double value) {
matr[pos1, pos2] = value;
};
void randomize() {
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
rnd = double(rand()) / double((RAND_MAX)+1.0);
printf("Rand : %d, C: %d, Val: %f \n",r,c, rnd);
this->setPos(r, c, rnd);
//matr[r, c] = rnd;
printf("New value R: %d C: %d Val: %f \n", r, c, matr[r,c]);
//rnd = 0;
}
}
};
void subtract_Scalar(double val) {
double curr_Val = 0;
double result = 0;
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
curr_Val = this->at(r, c);
result = curr_Val - val;
this->setPos(r, c, 0);
this->setPos(r, c, (float)result);
//this->setPos(r, c, 5);
//printf("SS CV : %f, Re: %f \n", curr_Val, result);
curr_Val = 0;
result = 0;
}
}
};
void print_matrix() {
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
printf("PM R : %d, C: %d Val: %f \n", r, c, matr[r,c]);
//printf("%f", this->at(r, c));
}
//printf("\n");
}
}
void clear_matrix() {
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
this->setPos(r, c, 0.0);
}
}
}
};
答案 0 :(得分:8)
Your program has undefined behavior because of the following line:
printf("PM R : %d, C: %d Val: %f \n", r, c, matr[r,c]);
matr[r,c]
does not access an element of the matrix. Due to the comma operator, it is simply matr[c]
, which evaluates to a pointer. You are printing the pointer using %f
. That's the undefined behavior part. You need to use matr[r][c]
to access the element of the matrix.
printf("PM R : %d, C: %d Val: %f \n", r, c, matr[r][c]);
Use of matr[r, c]
is not right.
See the documentation of the comma operator for further details.
Thanks to the keen eyes of @PeteBecker, the problem is different than what I initially thought.
It turns out, matr
is of type double*
. Hence matr[c]
evaluates to a double. Hence, the program does not have undefined behavior. It just accesses the c
-the element of matr
all the time regardless of the value of r
.
The problem starts with:
matr = new double[a, b];
It needs to be
matr = new double[a * b];
Anywhere the element of the matrix is accessed using matr[r, c]
, it needs to be matr[r*cols + c]
.
In at
, you need to use:
return matr[pos1 * cols + pos2];
In setPos
, you need to use:
matr[pos1 * cols + pos2] = value;
In randomize
, you need to use:
printf("New value R: %d C: %d Val: %f \n", r, c, matr[r*cols + c]);
In print_matrix
, you need to use:
printf("PM R : %d, C: %d Val: %f \n", r, c, matr[r*cols + c]);
You can simplify the code for accessing the elements by providing an overload of at
for const
non-const
objcts.
double& at(int r, int c) { return matr[r*cols + c]; }
double at(int r, int c) const { return matr[r*cols + c]; }
Then, setPos
can be implemented as:
void setPos(int pos1, int pos2, double value) {
at(pos1, pos2) = value;
};
The printf
lines can be updated to:
printf("New value R: %d C: %d Val: %f \n", r, c, at(r, c));
printf("PM R : %d, C: %d Val: %f \n", r, c, at(r, c));