When I debug the following code, I am told that there is an access violation. I tried changing this->arr[i][j] in the assignment operator to *(this->arr[i][j]) but that didn't work either as I was told that it was an illegal indirection.
Header
#ifndef MATRIX_H
#define MATRIX_H
class Matrix
{
public:
Matrix(int rSize=3, int cSize=3);
Matrix(const Matrix& m);
~Matrix();
bool setValue(int rSize, int cSize, int value);
bool getValue(int rVal, int cVal, int& value)const;
Matrix& operator= (const Matrix& m);
private:
int rowSize;
int columnSize;
int** arr;
};
Source
#include<iostream>
#include<cmath>
#include"Matrix.h"
using namespace std;
Matrix::Matrix(int rSize,int cSize)
{
columnSize = cSize;
rowSize = rSize;
arr = new int* [rowSize];
for(int i=0; i<rowSize; i++)
arr[i] = new int[columnSize];
for(int j=0; j<rowSize; j++)
{
for(int k=0; k<columnSize; k++)
arr[j][k] = 0;
}
}
Matrix::Matrix(const Matrix& m)
{
columnSize = m.columnSize;
rowSize = m.rowSize;
arr = new int* [rowSize];
for(int i=0; i<rowSize; i++)
{
arr[i] = new int [columnSize];
}
for(int i=0; i<rowSize; i++)
{
for(int j=0; j<columnSize; j++)
arr[i][j] = m.arr[i][j];
}
}
Matrix::~Matrix()
{
for(int i = 0; i < rowSize; ++i)
delete [] arr[i];
delete [] arr;
}
bool Matrix::setValue(int rVal, int cVal, int value)
{
if((rVal<0)||(cVal<0)||(rVal>rowSize-1)||(cVal>columnSize-1))
return false;
arr[rVal][cVal] = value;
return true;
}
bool Matrix::getValue(int rVal, int cVal, int& value)const
{
if((rVal<0)||(cVal<0)||(rVal>rowSize-1)||(cVal>columnSize-1))
return false;
value = arr[rVal][cVal];
return true;
}
Matrix& Matrix::operator= (const Matrix& m)
{
if(&m == this)
return(*this);
if(((this->rowSize)!= m.rowSize) || ((this->columnSize) != m.columnSize))
{
for(int i=0; i<rowSize; i++)
delete []arr[i];
delete[]arr;
rowSize = m.rowSize;
columnSize = m.columnSize;
arr = new int* [m.rowSize];
for(int r=0; r<rowSize; r++);
}
for(int j=0; j<rowSize; j++)
{
for(int k=0; k<columnSize; k++)
this->arr[j][k] = m.arr[j][k];
}
return(*this);
}
Driver
#include<iostream>
#include"Matrix.h"
using namespace std;
void main()
{
Matrix m(4, 5);
Matrix m2(m);
m2.setValue(1,2,12);
int x;
m2.getValue(1,2,x);
Matrix m3;
m3 = m2;
}
Matrix& Matrix::operator= (const Matrix& m)
for(int r=0; r<rowSize; r++);
You forgot to allocate :
arr[r] = new int [columnSize];
Related
I have written a program in c++, which implements some operations on matrix using class and operations.
The code is shown below:
matrix.h
#ifndef Matrix_h
#define Matrix_h
#include <iostream>
class Matrix
{
private:
int rows;
int cols;
int **Mat;
public:
Matrix ( int rows, int cols);
Matrix (const Matrix &other);
~Matrix ();
int* & operator[](const int &index) const ;
void operator=(const Matrix &other );
Matrix operator -()const;
Matrix operator -(const Matrix &other)const;
Matrix operator +(const Matrix &other)const ;
Matrix operator *(const Matrix &other)const;
Matrix operator *(const int &num)const;
int getMatrixRows(const Matrix &other){return other.rows;}
int getMatrixCols(const Matrix &other){return other.cols;}
friend Matrix operator *(const int & num,const Matrix &m)
{
return (m*num);
}
friend Matrix operator +(const int &num,const Matrix &t)
{
return (num+t);
}
friend std::ostream &operator<<(std::ostream &os, const Matrix &m)
{
for (int i=0; i < m.rows; ++i) {
for (int j=0; j < m.cols; ++j) {
os << m.Mat[i][j] << " " ;
}
os << '\n';
}
return os;
}
};
#endif
matrix.cpp
#include "Matrix.h"
#include <iostream>
Matrix::Matrix(int n_rows, int n_cols) //constructor
{
rows = n_rows;
cols = n_cols;
Mat = new int*[rows];
for(int i = 0; i < rows; ++i)
{
Mat[i] = new int[cols];
for(int j = 0; i < cols; ++j)
Mat[i][j] = 0;
}
}
Matrix::Matrix(const Matrix &other) //copy constructor
{
rows = other.rows;
cols = other.cols;
Mat = new int*[rows];
for(int i = 0; i < rows; ++i)
{
Mat[i] = new int[cols];
for(int j = 0; j < cols; ++j)
Mat[i][j] = other.Mat[i][j];
}
}
Matrix::~Matrix() //deconstructor
{
for(int i = 0; i < rows; ++i)
delete Mat[i];
delete[] Mat;
}
int* & Matrix::operator [](const int &index) const // overloading operator []
{
return Mat [index];
}
void Matrix::operator=(const Matrix &other ) // overloading operator =
{
if(Mat !=other.Mat && cols==other.cols && rows==other.rows)
{
for(int i=0;i<rows;i++)
for(int j=0;j<cols;j++)
Mat[i][j]=other.Mat[i][j];
}
}
Matrix Matrix::operator-()const // overloading operator -
{
Matrix temp(rows,cols);
for(int i=0;i<rows;i++)
for(int j=0;j<cols;j++)
temp.Mat[i][j]=Mat[i][j]*-1;
return temp;
}
Matrix Matrix::operator +(const Matrix &other)const //add 2 matrix
{
Matrix temp(rows,cols);
if (rows!=other.rows ||cols!=other.cols)
{
for(int i=0;i<rows;i++)
for(int j=0;j<cols;j++)
temp.Mat[i][j]=Mat[i][j];
return temp;
}
else
{
for(int i=0;i<rows;i++)
for(int j=0;j<cols;j++)
temp.Mat[i][j]+=other.Mat[i][j]+Mat[i][j];
}
return temp;
}
Matrix Matrix::operator *(const Matrix &other)const //multiplay matrix on the right
{
if (cols!=other.rows)
{
Matrix temp(cols,rows);
for(int i=0;i<rows;i++)
for(int j=0;j<cols;j++)
temp.Mat[i][j]=Mat[i][j];
return temp;
}
else
{
Matrix temp(cols,other.rows);
for(int i=0;i<rows;i++)
for(int j=0;j<other.cols;j++)
for(int k =0;k<cols;k++)
temp[i][j]+=Mat[i][k]*other.Mat[i][j];
return temp;
}
}
Matrix Matrix::operator *(const int &num)const //multiplay with number
{
Matrix temp(rows,cols);
for(int i=0;i<rows;i++)
for(int j=0;j<cols;j++)
temp.Mat[i][j]=Mat[i][j]*num;
return temp;
}
Matrix Matrix::operator -(const Matrix &other)const //matrix subtraction
{
Matrix temp(rows,cols);
if (rows!=other.rows ||cols!=other.cols)
{
for(int i=0;i<rows;i++)
for(int j=0;j<cols;j++)
temp.Mat[i][j]=Mat[i][j];
return temp;
}
else
{
for(int i=0;i<rows;i++)
for(int j=0;j<cols;j++)
temp.Mat[i][j]+=Mat[i][j]-other.Mat[i][j];
}
return temp;
}
main.cpp
#include "Matrix.h"
#include <iostream>
using namespace std;
void main()
{
Matrix m(2, 2);
m[0][0] = 2;
m[1][1] = 2;
cout << m << endl;
m = m;
const Matrix s = -m;
cout << m << endl << s << endl;
m = s + 2 * -m * m * 2 - s;
cout << m << endl << s << endl;
cout << s[1][1] << endl;
}
The expected output is :
2 0
0 2
2 0
0 2
-2 0
0 -2
-16 0
0 -16
-2 0
0 -2
-2
Well, the program seems to be compiled well , since there is no warnings or errors. However, when I run this program - it crushes with none input.
The dubugger is pointing the line Mat[i][j] = 0; to be suspicious (this line is in the constructor). Hopefully someone will be able to help.
The line for(int j = 0; i < cols; ++j) should be
for(int j = 0; j < cols; ++j).
Now it works.
So I wrote this:
Matrix.h:
#pragma once
class Matrix
{
private:
int m, n;
double** M = nullptr;
public:
Matrix();
Matrix(int,int);
Matrix(const Matrix&);
~Matrix();
void set_m(int);
void set_n(int);
int get_m() const;
int get_n() const;
void setM(double**,int,int);
double** getM() const;
void show();
Matrix operator*(Matrix&) const;
};
Matrix.cpp:
#include "Matrix.h"
#include<iostream>
using namespace std;
/*
*/
Matrix::Matrix()
{
set_n(1);
set_m(1);
delete[] M;
M = new double*[get_m()];
for (int i = 0; i < m; i++) {
M[i] = new double[get_n()];
}
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++) M[i][j] = 1.0;
}
Matrix::Matrix(int m_,int n_)
{
set_n(n_);
set_m(m_);
delete[] M;
M = new double *[get_m()];
for (int i = 0; i < m; i++) {
M[i] = new double[get_n()];
}
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++) M[i][j] = 1.0;
}
Matrix::Matrix(const Matrix& M_)
{
set_n(M_.get_n());
set_m(M_.get_m());
delete[] M;
M = new double*[get_m()];
for (int i = 0; i < m; i++) {
M[i] = new double[get_n()];
}
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++) M[i][j] = M_.getM()[i][j];
}
void Matrix::set_m(int m_) {
if (m_ > 0)
m = m_;
else
m = 1;
}
void Matrix::set_n(int n_) {
if (n_ > 0)
n = n_;
else
n = 1;
}
double** Matrix::getM() const {
return M;
}
Matrix Matrix::operator*(Matrix &M_) const
{
if (get_n() != M_.get_m()) {
if (get_m() != M_.get_n()) return Matrix();
else {
Matrix T(*this);
return M_*T;
}
}
else {
//n = m
Matrix R(get_m(), M_.get_n());
for (int i = 0; i < get_m(); i++) {
for (int j = 0; j < M_.get_n(); j++) {
double res = 0;
for (int k = 0; k < get_n(); k++) {
res += getM()[i][k] * M_.getM()[k][j];
}
R.getM()[i][j] = res;
}
}
return R;
}
}
int Matrix::get_m() const {
return m;
}
int Matrix::get_n() const {
return n;
}
void Matrix::setM(double** M_, int m_, int n_) {
set_m(m_);
set_n(n_);
for (int i = 0; i < get_m(); i++) {
delete M[i];
}
delete[] M;
M = new double*[m_];
for (int i = 0; i < m; i++) {
M[i] = new double[n_];
}
for (int i = 0; i < m_; i++)
for (int j = 0; j < n_; j++) M[i][j] = M_[i][j];
}
void Matrix::show() {
for (int i = 0; i < get_m(); i++) {
for (int j = 0; j < get_n(); j++) {
cout << getM()[i][j]<<" ";
}
cout << endl;
}
}
Matrix::~Matrix()
{
for (int i = 0; i < get_m(); i++) {
delete M[i];
}
delete[] M;
}
It crashes at void Matrix::setM(...) when I try to delete M[i] for i = 1; it doe perfectly fine for i=0; but crashes later and I do not have a rational explanation why does it do that. I can see the debugger showing me that the memory cannot be read even before it actually crashing but I do not understand how to fix it. Thanks in advance!
You are setting your m before deleting your array based on the old value of m and end up deleting your old array using the new value of m. You should first delete your array, then set mm, and then create your new array.
class Matrix{
double **val;
int rows,cols,errorCode;
public:
Matrix();
Matrix(int);
Matrix(int, int);
~Matrix();
void Print();
void Read();
double Get(int, int);
void Assign(int,int,double);
void Addition(Matrix&);
void Subtraction(Matrix&);
Matrix Multiply(Matrix&);
void Multiply(double);
};
Matrix::Matrix(){
//First array go with rows.
val = new double*[1];
val[1] = new double[1];
rows = 1;
cols = 1;
errorCode = 0;
}
Matrix::Matrix(int n){
rows = n;
cols = n;
val = new double*[rows];
for(int i = 0;i<rows;i++){
val[i] = new double[cols];
}
}
Matrix::Matrix(int n,int m){
rows = n;
cols = m;
val = new double*[rows];
for(int i = 0;i<rows;i++){
val[i] = new double[cols];
}
}
Matrix::~Matrix(){
for(int i=0;i<rows;i++){
delete[] val[i];
}
delete[] val;
}
Matrix Matrix::Multiply(Matrix &a){
if(cols != a.rows){
Matrix b;
b.errorCode=111; //That means dimensions are not valid;
return b;
}
else{
Matrix b(rows,a.cols);
double p;
for(int i=0;i<rows;i++){
for(int j=0;j<a.cols;j++){
p=0;
for(int k=0;k<cols;k++){p += val[i][k]*a.val[k][j];}
b.Assign(i,j,p);
}
}
return b;
}
}
When i compile it seems to be ok, but when i run it doesn't work and i don't understand why...it says "program stoped worked" and returned error 255
If needed i can put all the code i write...
I added constructors...
unfutunatly i can not post images... it says process returned 255, and here is an alert from windows that the program was not working corectly and it stoped working...
Here is all the code if someone have time and if it helps you to understand better..
#include <iostream>
using namespace std;
class Matrix{
double **val;
int rows,cols,errorCode;
public:
Matrix();
Matrix(int);
Matrix(int, int);
~Matrix();
void Print();
void Read();
double Get(int, int);
void Assign(int,int,double);
void Addition(Matrix&);
void Subtraction(Matrix&);
Matrix Multiply(Matrix&);
void Multiply(double);
};
Matrix::Matrix(){
//First array go with rows.
val = new double*[1];
val[0] = new double[1];
rows = 1;
cols = 1;
errorCode = 0;
}
Matrix::Matrix(int n){
rows = n;
cols = n;
val = new double*[rows];
for(int i = 0;i<rows;i++){
val[i] = new double[cols];
}
}
Matrix::Matrix(int n,int m){
rows = n;
cols = m;
val = new double*[rows];
for(int i = 0;i<rows;i++){
val[i] = new double[cols];
}
}
Matrix::~Matrix(){
for(int i=0;i<rows;i++){
delete[] val[i];
}
delete[] val;
}
void Matrix::Read(){
for(int i=0;i<rows;i++){
delete[] val[i];
}
delete[] val;
cout<<"Give the matrix dimensions (rows and cols) : ";
cin>>rows>>cols;
val = new double*[rows];
for(int i = 0;i<rows;i++){
val[i] = new double[cols];
}
cout<<"Give the matrix values: "<<endl;
for(int i = 0;i<rows;i++){
for(int j = 0;j<cols;j++){ cin>>val[i][j];}
}
}
void Matrix::Print(){
cout<<"The matrix with "<<rows<<" rows and "<<cols<<" cols, have next values: "<<endl;
for(int i = 0;i<rows;i++){
for(int j = 0;j<cols;j++){ cout<<val[i][j]<<" ";}
cout<<endl;
}
}
double Matrix::Get(int n, int m){
return val[n-1][m-1];
}
void Matrix::Assign(int n,int m,double v){
val[n-1][m-1] = v;
}
void Matrix::Addition(Matrix &a){
if(rows != a.rows || cols !=a.cols){
errorCode=111; //That means dimensions are not equal;
}
else{
for(int i = 0;i<rows;i++){
for(int j = 0;j<cols;j++){ val[i][j] += a.val[i][j];}
}
}
}
void Matrix::Subtraction(Matrix &a){
if(rows != a.rows || cols !=a.cols){
errorCode=111; //That means dimensions are not equal;
}
else{
for(int i = 0;i<rows;i++){
for(int j = 0;j<cols;j++){ val[i][j] -=a.val[i][j];}
}
}
}
void Matrix::Multiply(double x){
for(int i = 0;i<rows;i++){
for(int j = 0;j<cols;j++){ val[i][j] *= x;}
}
}
Matrix Matrix::Multiply(Matrix &a){
if(cols != a.rows){
errorCode=111; //That means dimensions are not equal;
Matrix b;
return b;
}
else{
Matrix b(rows,a.cols);
double p;
for(int i=0;i<rows;i++){
for(int j=0;j<a.cols;j++){
p=0;
for(int k=0;k<cols;k++){p += val[i][k]*a.val[k][j];}
b.Assign(i,j,p);
}
}
return b;
}
}
int main(){
Matrix a,b(2,3);
b.Assign(1,1,0);
b.Assign(1,2,3);
b.Assign(1,3,5);
b.Assign(2,1,5);
b.Assign(2,2,5);
b.Assign(2,3,2);
b.Print();
a.Read();
a.Print();
cout<<endl;
//when i read a i put 3x2 matrix, so the multiplying can be done.
Matrix c=a.Multiply(b);
c.Print();
return 0;
}
problem appear when i try to use function: Matrix Multiply(Matrix&).
There's an error in your default constructor:
val = new double*[1];
val[1] = new double[1];
1 is not a valid index for val, this should be:
val[0] = new double[1];
I got problem using function to read matrix from file...
my class looks like this:
#include<iostream>
#include<cmath>
#include<string>
#include<fstream>
using namespace std;
class Matrix
{
public:
Matrix(int, int);
Matrix(const Matrix& copyMatrix);
~Matrix();
Matrix(const char *sciezka);
Matrix& wypelnij(string);
friend ostream& operator<< (ostream&, Matrix&);
Matrix& operator+= (const Matrix&);
Matrix& operator-= (const Matrix&);
Matrix& operator*= (const Matrix&);
Matrix& operator= (const Matrix&);
friend Matrix operator* (const Matrix & left, const Matrix & right);
friend Matrix operator+ (const Matrix & left, const Matrix & right);
friend Matrix operator- (const Matrix & left, const Matrix & right);
class AllocError{};
class OpenError{};
class IncorrectSize{};
private:
double **macierz;
unsigned int wiersze, kolumny;
};
constructors:
Matrix::Matrix(int x = 1, int y = 1): wiersze(x), kolumny(y)
{
if (wiersze < 1 || kolumny < 1)
{
throw AllocError();
}
macierz = new double*[wiersze];
for (unsigned i = 0; i < wiersze; i++)
{
macierz[i] = new double[kolumny];
for (unsigned j = 0; j < kolumny; j++)
{
macierz[i][j] = 0;
}
}
}
Matrix::Matrix(const Matrix& copyMatrix)
{
wiersze=copyMatrix.wiersze;
kolumny=copyMatrix.kolumny;
macierz = new double*[wiersze];
for (unsigned i = 0; i < wiersze; i++)
{
macierz[i] = new double[kolumny];
for (unsigned j = 0; j < kolumny; j++)
{
macierz[i][j] = copyMatrix.macierz[i][j];
}
}
}
and finally the function
Matrix::Matrix(const char *sciezka)
{
ifstream plik(sciezka);
if (plik.good() != true)
{
throw OpenError();
}
unsigned w, k;
plik >> w >> k;
if (w < 1 || k < 1) throw AllocError();
double **temp = new double*[w];
double *pamiec = new double[w * k];
for (unsigned i = 0; i < w; i++)
{
temp[i] = pamiec + (i * k);
}
for (unsigned i = 0; i < w; i++)
{
for (unsigned j = 0; j < k; j++)
{
plik >> temp[i][j];
}
}
wiersze=w;
kolumny=k;
macierz=temp;
//for (unsigned i = 0; i < w; i++) //IT WORKS TOO
// {
// macierz[i] = temp[i];
// }
for (unsigned i = 0; i < w; i++)
{
for (unsigned j = 0; j < k; j++)
{
macierz[i][j] = temp[i][j];
}
}
plik.close();
//delete [] *temp;
//delete [] temp;
}
It works just fine when I dont use delete at the end of the funtion, when I do, some numbers are wrong. If I dont it crashes after finishing all calculations Matrix A("text.txt") Matrix B(5,5) Fill.B("B") Matrix C(5,5)
C=A+B etc...
#edit
I just made it work changing the end of the F to:
wiersze=w;
kolumny=k;
//macierz=temp;
macierz = new double*[w];
for (unsigned i = 0; i < w; i++)
{
macierz[i] = new double[k];
for (unsigned j = 0; j < k; j++)
{
macierz[i][j] = temp[i][j];
}
}
plik.close();
delete [] *temp;
delete [] temp;
}
is there any easier way to read from file? I dont really like this code
For deleting the matrix you should follow the reverse order of allocation, following should do :
for (unsigned i = 0; i < w; i++)
{
delete [] macierz[i] ;
}
delete [] macierz ;
for some reason, I seem to be having an exception whenever I call the following (assume A,B & C are all matrices, and that no matrix multiplication rules are broken):
c=a*b;
I have been stepping through my code for hours now, and cannot for the life of me find whats wrong.
any takers? I think it might be an issue with either the allocate() or clear() functions, or the copy constructor/assignment operator.
Thanks in advance!
// 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
Quite a lot of code but I just looked at the copy constructor and it has two serious mistakes in it.
First mistake
matrix(const matrix<mType> &m) {
if (origin)
clear();
origin is uninitialized at this point, so you cannot test it's value. Just remove these two lines. Remember a constructor initializes a new object, it's wrong if a constructor is testing the object for what is already there.
Second mistake
Your copy constructor doesn't copy anything! It creates a matrix of the right size but it doesn't copy the matrix values!
I would guess the first error is the cause of your crash, the second error will just mean you get garbage results.