один случай влияет на другой, хотя это не должно - PullRequest
0 голосов
/ 29 декабря 2011

Я создал матричный класс MxN типа T и попытался создать экземпляр и распечатать его. Возникла проблема, которую вы видите в конце кода (когда я сделал cout << m;) Эта команда распечатала матрицу с некоторыми полями другой матрицы - фактически первый столбец m совпадает с последним столбцом m2, и я не понимаю, почему?

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <stdexcept>

using namespace std;


template<typename T, int M>
class matrix_helper {
public:
    T& operator[](int j) {
        return data[j];
    }

private:
    T data[M];  
};

template<typename T, int N, int M>
class matrix {
public:
    explicit matrix(const vector<T>& v) {
        if (v.size() != M * N)
            throw invalid_argument("Incorrect input data");

        int i=0, j=0;

        for (int k = 0; k != M*N; ++k) {
            data[i][j] = v[k];
            ++i;
            if (i == M) { // i:0..M
                i = 0;
                ++j;
            }
        }
    }
    matrix_helper<T,M> operator[](int j) {
        matrix_helper<T, M> mh;
        for(int i=0; i != M; ++i) {
            mh[i] = data[j][i];
        }
        return mh;
    }
    matrix<T,M,N>& operator+=(matrix<T,M,N>& m) {
        for(int i=0; i != N;++i)
            for(int j=0; j != M;++j) {
                this->data[i][j] += m[i][j]; // or - should I rather use (*this)[i][j] += ... ???
            }

        return *this;
    }

private:
    T data[N][M];
};

template<typename T, int N, int M>
ostream& operator<<(ostream& os, matrix<T,N,M> & m) {
        int i=0, j=0;
        for (int k = 0; k != M*N; ++k) {
            os << m[i][j] << '\t';
            ++i;
            if (i == M) { // i:0..M
                i = 0;
                ++j;
                os << endl;
            }
        }
        os << endl;
}



int rnd(int max = 20) { return rand() % max; }
void print(int i) { cout << i << ' '; }

int main() {

    vector<int> u, v; 
    for (int i = 0; i != 20; ++i) u.push_back(i);

    for (int i = 20; i != 40; ++i) v.push_back(i);
    //for_each(u.begin(), u.end(), print);


    matrix<int, 4,5> m(u);
    matrix<int, 4,5> m2(v);
    cout << m; // returns: 24 1 2 3 4,... Why not 0 1 2 3 4 ???


    cout << endl;
    system("pause");
    return 0;   
}

Ответы [ 3 ]

4 голосов
/ 29 декабря 2011

Вы объявляете массив [N][M], но ваш код инициализации обрабатывает его так, как если бы он был [M][N].

1 голос
/ 29 декабря 2011

Тот факт, что вы видите значения от m2 в m, объясняется тем, что ваш матричный процессор записывает вне границ массива данных, перезаписывая все, что находится в стеке, в непосредственной близости.Именно эта строка:

data[i][j] = v[k];

записывает вне границ массива.

также ваше

ostream& operator<< ()

должно возвращать значение

0 голосов
/ 29 декабря 2011

Вам нужно выделить память для матрицы :: массив данных.

Вы можете изменить следующим образом:

T data[N][M]; => std::vector< std::vector<T> > data;

Затем подготовьте векторыв конструкторе

data.assign(M, std::vector<T>());
for (int x=0; x<M; ++x)
    data[x].assign(N, T());
...