Как правильно назначить массив внутри класса C ++? - PullRequest
0 голосов
/ 19 марта 2019

У меня есть матрица классов C ++ (см. Фрагмент кода ниже).

В моем методе рандомизации я устанавливаю все значения matr (matr - матрица 2x2).

Когда я вызываю print_matrix, он дублирует элементы (1,0) и (1,1) и печатает их оба дважды, а также не печатает (0,0) или (0,1).

Что я делаю неправильно?

См. Вывод ниже.

enter image description here

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

    };

1 Ответ

8 голосов
/ 19 марта 2019

Ваша программа имеет неопределенное поведение из-за следующей строки:

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] не правильно.

См. документацию оператора запятой для получения дополнительной информации.


Обновление

Благодаря острым глазам @PeteBecker, проблемаотличается от того, что я первоначально думал.

Оказывается, matr имеет тип double*.Следовательно, 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]);

Вы можете упростить код для доступа к элементам, обеспечив перегрузку at для const не- 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));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...