2012-09-12 89 views
0

出於某種原因,我似乎具有每當我調用下面(假設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 

修訂:

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

是否有任何理由不使用具有各種許可證的優秀線性代數庫之一?我建議Eigen例如... – enobayram

+1

http://codereview.stackexchange.com/是更合適的。 – ephemient

回答

4

相當多的代碼,但我只是看着拷貝構造函數,它有它兩個嚴重的錯誤。

的第一個錯誤

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

原點在這一點上未初始化,所以無法測試它的價值。只要刪除這兩行。記住一個構造函數初始化一個新的對象,如果一個構造函數正在測試已經存在的對象,這是錯誤的。

第二個錯誤

你的拷貝構造函數不會複製任何東西!它創建一個正確大小的矩陣,但它不會複製矩陣值!

我猜想第一個錯誤是你的崩潰的原因,第二個錯誤只會意味着你得到垃圾結果。

+0

在乘法過程中看到崩潰的原因是,使用複製構造函數返回結果時會複製結果。 –

+0

你可以使用':origin(NULL)'來顯示修正後的版本嗎? –

+0

@BobFincheimer我不會添加':origin(NULL)'我只是刪除if語句,原點被分配在下一行。 – john