1

現在、テンプレート化されたマトリックス クラスを実装するプロジェクトに取り組んでいます。ただし、テスト関数を実行しようとすると、プログラムがクラッシュしてコア ダンプが発生します。以下は私が得る出力です:

0 0
[3 3 1 2 3 4 5 6 9 8 10]
[1 2 3 
 4 5 6
 9 8 10]
stream out sucessInvalid Input for matrix
stream in sucessError: matrix Multiplication not defined.
[1 2 3 
 4 5 6
 9 8 10]

Error: The addition of two matrices of different demensions is not defined.


Error: The addition of two matrices of different demensions is not defined.

7700640
7700576
Error: The addition of two matrices of different demensions is not defined.
*** glibc detected *** ./a.out: free(): invalid pointer: 0x00000030143b0778 ***
======= Backtrace: ========= <Continues> ...

呼び出し機能は次のとおりです。

TestingMatrix(){
matrix<int> a, b, c;
//Three empty matrices are created
cout << a.numrows() << " " << a.numcols() << endl; // yields 0 0
cin >> a; // User types [3 3 1 2 3 6 5 4 9 8 10]
// This will create a 3 by 3 matrix
cout << a;
cin >> b; //User types [3 2 9 1 2 3 4 5]
cout << b;
c=a*b;



cout << c << endl; 
cout << b+c << endl; 
matrix<int> d(5*b); // d is initialized to 5*b
cout << d << endl; 
cout << a[0][0] << endl;
//Should printout 1
cout << a[1][2] << endl;
//Should printout 4
d = a + b;
//This should cause an exception that you
//are able to handle; The sizes of a and b don’t agree.
}//End of TestingMatrix() function

マトリックス クラスは次のとおりです。

// matrix.h
#ifndef matrix_H
#define matrix_H
#include <iostream>
#include <cstdlib>
using namespace std;
template <class mType> class matrix {
public:
    matrix() : N(0), M(0), origin(NULL) { /* EMPTY */ }
    matrix(int n, int m): N(n), M(m), origin(NULL) {
        allocate(n,m);
    }

    ~matrix() {
        clear();
    }

    matrix & operator=(const matrix &rhs) {

        if (this != &rhs) {     //Check to see they're not the same instance

            this->clear();
            this->allocate(rhs.numrows(), rhs.numcols());
            for(int i=0; i<N; ++i)
                for (int j=0; j<M; ++j)
                    this->origin[i][j] = rhs[i][j];
            }

        return *this;
    }

    matrix & operator+=(const matrix &rhs) {
        try {
            if (    this->numrows() != rhs.numrows() ||
                this->numcols() != rhs.numcols() ) 
                throw 1;
        }
        catch (int e)
        {
            cerr << "Error: The addition of two matrices of different demensions is not defined." << endl;
            return *this;
        }

        for(int i=0; i<N; ++i)
            for (int j=0; j<M; ++j)
                this->origin[i][j] += rhs[i][j];
        return *this;
    }


    const matrix operator+(const matrix &rhs) const {
       matrix tmp = *this;     // tmp copy so we can use the += operator
       return (tmp += rhs);     // return answer
    }

    const matrix operator*(const matrix &rhs) const {
        try {
            if (    this->numcols() != rhs.numrows() )
                throw 1;
        }
        catch (int e)
        {
            cerr << "Error: matrix Multiplication not defined." << endl;
            return *this;
        }
        matrix<mType> returnmatrix(this->numrows(), rhs.numcols());

        for (int i=0; i<returnmatrix.numrows(); ++i)
            for (int j=0; j<returnmatrix.numcols(); ++j)
                for (int k=0; k < this->numcols(); ++k)
                    returnmatrix[i][j] += *this[i][k] * rhs[k][j];
        return returnmatrix;

     }


    inline int const numrows() const {
        return N;
    }

    inline int const numcols() const {
        return M;
    }


    void allocate(int n, int m) {
        if (origin)
            clear();
        origin = new mType* [n];
        for (int i=0; i<n; ++i)
            origin[i] = new mType[m];
        M=m;
        N=n;        
    }
    void clear() {
        if (origin) {
            for(int i = 0; i < N; i++)
                    delete[] origin[i];
            delete origin;
        }

        M=N=0; // Reset

        origin=NULL; 
    }



    mType* operator [] (const int index)  { return origin[index]; }
    const mType* operator [] (const int index) const  { return origin[index]; }



    friend matrix<mType> operator*( mType factor, const matrix<mType> rhs ) {
        matrix<mType> out(rhs.numrows() , rhs.numcols());       
            for (int i=0; i<rhs.numrows(); ++i) {
                for (int j=0; j<rhs.numcols(); ++j) {
                    out[i][j] = rhs[i][j]*factor;
                }
            }
        return out;
    }

    friend ostream& operator<< (ostream& out, const matrix<mType>& A) {

        if (A.numrows() > 0 && 0 <  A.numcols()) {
            out <<"[";
            for (int j=0; j<A.numcols(); ++j) {
                out << A[0][j] << " ";
            }
            for (int i=1; i<A.numrows(); ++i) {
                out << endl;
                for (int j=0; j<A.numcols(); ++j) {
                    out << " " << A[i][j];
                }
            }
            out << "]" <<endl;

        }
        return out;
    }

     friend istream& operator>> (istream& in, matrix<mType> &A)  {
        //[3 2 9 1 2 3 4 5]
        //toss first char
        try {
            if (in.get() != '[')
                throw 1;
            int N, M;
            mType tmp;
            in >> N;
            in >> M;

            A = matrix<mType>(N,M);
            for (int i=0; i<N; ++i)
                for (int j = 0; j < M; j++)
                {   
                    in >> tmp;
                    A[i][j] = tmp;
                }
            in.get();
        }
        catch (int e) {
            cerr << "Invalid Input for matrix" << endl;

        }

        return in;
    }


private: 
    int N, M;
    mType ** origin;


};


#endif

これをどのように解決するかについて誰か考えがありますか? この問題のソースについてはかなり迷っています。

前もって感謝します。

4

2 に答える 2

0

リソースを動的に割り当てたので、3 つのルールに従ってコピー コンストラクターを実装する必要があります。現在、コピー構築は、データ自体をコピーせずに、コンパイラによって生成されたコピー コンストラクターを使用して、基になるデータへのポインターのコピーを作成します。

加算演算子には少なくとも 1 つのコピー構造があります。

const matrix operator+(const matrix &rhs) const {
   matrix tmp = *this; // copy!
   return (tmp += rhs); // potentially another copy
}
于 2012-09-12T16:06:52.243 に答える
0

いいえcopy c-tor、コンパイラはデフォルトを生成しますがmemberwise-copy、クラスにリソースを動的に割り当てている場合は、独自のcopy c-torが必要ですdeep-copy

于 2012-09-12T16:07:24.723 に答える