我有这个C ++类Matrix(请参见下面的代码片段)。

在我的随机方法中,我设置了matr的所有值(matr是2x2矩阵)。

当我调用print_matrix时,它正在复制元素(1,0)和(1,1)并将它们都打印两次,以及不打印(0,0)或(0,1)。

我做错了什么?

请参见下面的输出。

c++ - 分配给C++类中的数组的正确方法是什么?-LMLPHP

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);
            }
        }
    }

    };

最佳答案

由于以下行,您的程序具有未定义的行为:

printf("PM R : %d, C: %d Val: %f \n", r, c, matr[r,c]);


matr[r,c]不访问矩阵的元素。由于使用了逗号运算符,因此它只是matr[c],其结果为一个指针。您正在使用%f打印指针。那是未定义的行为部分。您需要使用matr[r][c]访问矩阵的元素。

printf("PM R : %d, C: %d Val: %f \n", r, c, matr[r][c]);




matr[r, c]的使用不正确。

有关更多详细信息,请参见the documentation of the comma operator



更新资料

由于@PeteBecker敏锐的眼睛,这个问题与我最初的想法不同。

事实证明,matrdouble*类型。因此,matr[c]计算结果为双精度。因此,该程序没有未定义的行为。不管c的值如何,它始终一直访问matr-r的元素。

问题开始于:

matr = new double[a, b];


它必须是

matr = new double[a * b];


使用matr[r, c]访问矩阵元素的任何位置,都必须为matr[r*cols + c]

at中,您需要使用:

return matr[pos1 * cols + pos2];


setPos中,您需要使用:

matr[pos1 * cols + pos2] = value;


randomize中,您需要使用:

printf("New value R: %d C: %d Val: %f \n", r, c, matr[r*cols + c]);


print_matrix中,您需要使用:

printf("PM R : %d, C: %d Val: %f \n", r, c, matr[r*cols + c]);


通过为atconst对象提供const的重载,可以简化用于访问元素的代码。

double& at(int r, int c) { return matr[r*cols + c]; }
double at(int r, int c) const { return matr[r*cols + c]; }


然后,setPos可以实现为:

  void setPos(int pos1, int pos2, double value) {
     at(pos1, pos2) = value;
  };


printf行可以更新为:

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));

09-17 20:58