Core Dump при тестировании мини Matrix ADT

В настоящее время я работаю над проектом, реализующим шаблонный класс матрицы; однако всякий раз, когда я пытаюсь запустить свою тестовую функцию, происходит сбой программы и дамп ядра. Вот вывод, который я получаю:

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

Функция вызова:

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

Класс матрицы выглядит следующим образом:

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

У кого-нибудь есть идеи относительно того, как решить эту проблему? Я довольно растерян относительно источника этой проблемы.

Заранее спасибо.

1

Решение

Поскольку у вас есть динамически распределенные ресурсы, вы должны следовать правило трех и реализовать конструктор копирования. В настоящее время конструкция копирования будет использовать созданный компилятором конструктор копирования, делая копию указателя на базовые данные, не копируя сами данные.

В вашем операторе сложения есть хотя бы одна копия конструкции:

const matrix operator+(const matrix &rhs) const {
matrix tmp = *this; // copy!
return (tmp += rhs); // potentially another copy
}
0

Другие решения

У вас нет copy c-tor и компилятор сгенерирует дефолт, который делает memberwise-copy, но если у вас есть динамически распределенные ресурсы в классе — у вас должен быть свой copy c-tor, что сделать deep-copy,

0