乘法矩阵的分段错误

时间:2012-09-12 20:29:38

标签: c++ segmentation-fault operator-keyword

出于某种原因,每当我调用以下内容时,我似乎都有异常(假设A,B和C都是矩阵,并且没有矩阵乘法规则被破坏):

c=a*b; 

我现在已经在我的代码中踩了好几个小时,而且在我的生活中找不到什么错误。

任何接受者?我认为它可能是allocate()或clear()函数或复制构造函数/赋值运算符的问题。

提前致谢!

// 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(const matrix<mType> &m) {
        if (origin)
                clear();
        origin = new mType* [m.numrows()];
        for (int i=0; i<m.numrows(); ++i)
            origin[i] = new mType[m.numcols()];

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

    friend const matrix operator*(const matrix &that, const matrix &rhs) {
        try {
            if (    that.numcols() != rhs.numrows() )
                throw 1;
        }
        catch (int e)
        {
            cerr << "Error: matrix Multiplication not defined." << endl;
            return that;
        }
        matrix<mType> returnmatrix(that.numrows(), rhs.numcols());
        int x=0;
        for (int i=0; i<returnmatrix.numrows(); ++i)
            for (int j=0; j<returnmatrix.numcols(); ++j)
                for (int k=0; k < that.numcols(); ++k){
                    cout << (++x)<<endl;
                    returnmatrix[i][j] += that[i][k] * rhs[k][j];}
        cout << "rt" <<endl;    
        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 (this->origin) {
        for(int i = 0; i < N; i++)
                delete[] origin[i];
        delete this->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();
            in.ignore();
        }
        catch (int e) {
            cerr << "Invalid Input for matrix" << endl;

        }

        return in;
    }


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


};


#endif

REVISED:

// 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(const matrix<mType> &m) {

    origin = new mType* [m.numrows()];
    for (int i=0; i<m.numrows(); ++i)
        origin[i] = new mType[m.numcols()];
    for (int i=0; i<N;++i)
        for (int j = 0; j < M; j++)
        {
            origin[i][j] = m[i][j];
        }


}
matrix(int n, int m): N(n), M(m), origin(NULL) {
    allocate(n,m);
    for (int i=0; i<N;++i)
        for (int j = 0; j < M; j++)
        {
            origin[i][j] = 0;
        }
}

~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
}

friend const matrix operator*(const matrix &that, const matrix &rhs) {
    try {
        if (    that.numcols() != rhs.numrows() )
            throw 1;
    }
    catch (int e)
    {
        cerr << "Error: matrix Multiplication not defined." << endl;
        return that;
    }
    matrix<mType> returnmatrix(that.numrows(), rhs.numcols());
    int x=0;
    for (int i=0; i<returnmatrix.numrows(); ++i)
        for (int j=0; j<returnmatrix.numcols(); ++j)
            for (int k=0; k < that.numcols(); ++k){
                cout << (++x)<<endl;
                returnmatrix[i][j] += that[i][k] * rhs[k][j];}
    cout << "rt" <<endl;    
    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 (this->origin) {
        for(int i = 0; i < N; i++)
                delete[] origin[i];
        delete this->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();
        in.ignore();
    }
    catch (int e) {
        cerr << "Invalid Input for matrix" << endl;

    }

    return in;
}


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


};


#endif

1 个答案:

答案 0 :(得分:4)

相当多的代码,但我只是看了一下复制构造函数,它有两个严重的错误。

第一个错误

matrix(const matrix<mType> &m) {
    if (origin)
            clear();

此时原点尚未初始化,因此您无法测试其值。只需删除这两行。记住一个构造函数初始化一个新对象,如果一个构造函数正在测试该对象已经存在的东西,那就错了。

第二个错误

您的复制构造函数不会复制任何内容!它会创建一个大小合适的矩阵,但不会复制矩阵值!

我猜第一个错误是导致崩溃的原因,第二个错误只是意味着你得到了垃圾结果。