出于某种原因,每当我调用以下内容时,我似乎都有异常(假设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
答案 0 :(得分:4)
相当多的代码,但我只是看了一下复制构造函数,它有两个严重的错误。
第一个错误
matrix(const matrix<mType> &m) {
if (origin)
clear();
此时原点尚未初始化,因此您无法测试其值。只需删除这两行。记住一个构造函数初始化一个新对象,如果一个构造函数正在测试该对象已经存在的东西,那就错了。
第二个错误
您的复制构造函数不会复制任何内容!它会创建一个大小合适的矩阵,但不会复制矩阵值!
我猜第一个错误是导致崩溃的原因,第二个错误只是意味着你得到了垃圾结果。