I am currently working on a project implementing a templated matrix class; however, whenever I try to run my test function, the program crashes and core dumps. The following is the output I get:
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> ...
The Calling function is:
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
The matrix class is as follows:
// 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
Does anyone have any idea as to how resolve this? I’m pretty lost as to the source fo this issue.
Thanks in advance.
Since you have dynamically allocated resources, you should follow the rule of three and implement a copy constructor. Currently a copy construction will use the compiler generated copy constructor, making a copy of the pointer to the underlying data, without copying the data itself.
There is at least one copy construction in your addition operator: