I got here class Matrix, the problem is that it crashes after one line of code: e.g Matrix A(2,2);
So it's most likely constructor, but the thing is that when I copied my constructor into other class Matrix it worked just fine... I think I am blind
#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& mac_cin(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 RangeError{};
class AllocError{};
class OpenError{};
class IncorrectSize{};
private:
double **macierz;
unsigned int wiersze, kolumny;
};
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];
}
}
}
Matrix::~Matrix()
{
delete [] macierz;
for (unsigned i = 0; i < wiersze; i++)
{
delete [] macierz[i];
}
}
/*
Matrix::Matrix(const char *sciezka)
{
ifstream plik(sciezka);
if (plik.good() != true)
{
throw OpenError();
}
plik >> wiersze >> kolumny;
macierz = new double*[wiersze];
for (unsigned i = 0; i < wiersze; i++)
{
for (unsigned j = 0; j < kolumny; j++)
{
plik >> macierz[i][j];
}
}
//delete [] *macierz;
//delete [] macierz;
}
*/
ostream & operator<< (ostream& wyjscie, Matrix& co)
{
for (unsigned i = 0; i < co.wiersze; i++)
{
for (unsigned j = 0; j < co.kolumny; j++)
{
wyjscie << co.macierz[i][j] << " ";
}
cout << endl;
}
}
Matrix operator* (const Matrix & left, const Matrix & right)
{
Matrix nlr(left);
return nlr *= right;
}
Matrix operator+ (const Matrix & left, const Matrix & right)
{
Matrix nlr(left);
return nlr += right;
}
Matrix operator- (const Matrix & left, const Matrix & right)
{
Matrix nlr(left);
return nlr -= right;
}
Matrix& Matrix::operator+=(const Matrix& co)
{
if(this->wiersze!=co.wiersze || this->kolumny!=co.kolumny)
{
throw IncorrectSize{};
}
for(unsigned i=0; i<this->wiersze; i++)
{
for(unsigned j=0; j<this->kolumny; j++)
{
this->macierz[i][j] = this->macierz[i][j]+co.macierz[i][j];
}
}
return *this;
}
Matrix& Matrix::operator-=(const Matrix& co)
{
if(this->wiersze!=co.wiersze || this->kolumny!=co.kolumny)
{
throw IncorrectSize{};
}
for(unsigned i=0; i<this->wiersze; i++)
{
for(unsigned j=0; j<this->kolumny; j++)
{
this->macierz[i][j] = this->macierz[i][j]-co.macierz[i][j];
}
}
return *this;
}
Matrix& Matrix::operator*=(const Matrix& co)
{
if(this->wiersze!=co.wiersze || this->kolumny!=co.kolumny)
{
throw IncorrectSize{};
}
for(unsigned i=0; i<this->wiersze; i++)
{ // moze double temp=0;
for(unsigned j=0; j<this->kolumny; j++)
{
this->macierz[i][j] = this->macierz[i][j]*co.macierz[i][j]; // temp+=
}
} // moze newMatrix.macierz[i][j] = temp;
return *this;
}
Matrix& Matrix::operator=(const Matrix& co)
{
if(this->wiersze!=co.wiersze || this->kolumny!=co.kolumny)
{
throw IncorrectSize{};
}
for(unsigned i=0; i<this->wiersze; i++)
{
for(unsigned j=0; j<this->kolumny; j++)
{
this->macierz[i][j] = co.macierz[i][j];
}
}
return *this;
}
Matrix& Matrix::mac_cin(string mac) {
int i,j;
cout << "Podaj zawartosc macierzy\n";
for(i=0; i<this->wiersze; i++)
{
for(j=0; j<this->kolumny; j++)
{
cout << mac << "[" << i << "][" << j << "] = ";
cin >> this->macierz[i][j];
}
}
return *this;
}
int main()
{
Matrix A(2,2);
A.mac_cin("A");
Matrix okA(A);
return 0;
}
When I use TDM-GGC 32 Bit it works BUT when I change main to:
int main()
{
Matrix A(2,2);
A.mac_cin("A");
Matrix okA(A);
Matrix B(3,3);
B.mac_cin("B");
Matrix okB(B);
Matrix C(3,3);
Matrix okC(C);
cout << endl;
cout << "A: " << endl << A << endl << endl;
cout << "B: " << endl << B << endl << endl;
C=A+B;
cout << "A+B: " << endl << C << endl << endl;
C=A-B;
cout << "A-B: " << endl << C << endl << endl;
C=A*B;
cout << "A*B: " << endl << C << endl << endl;
C=A;
C+=B;
cout << "A+=B: " << endl << C << endl << endl;
C=A;
C-=B;
cout << "A-=B: " << endl << C << endl << endl;
C=A;
C*=B;
cout << "A*=B: " << endl << C << endl << endl;
system("PAUSE");
return 0;
}
then it's not working again (and it works on similar matrix with my constructors...)
The overloaded operator << should return the ostream object i.e.wyjscie, this enables chaining while using the cout << A << ..., etc.
This is where your code is crashing, so fix as follows :
ostream & operator<< (ostream& wyjscie, Matrix& co)
{
//...
wyjscie << endl;
return wyjscie ; // <---- Notice this
}
Note : There might be other errors too
I'm not sure if this is the source of your problem, but in the destructor you are deleting macierz right before iterating over it and accessing elements. You should iterate over it first, and delete the whole thing afterwards.
Related
I am getting a segmentation fault error when compiling my code. I don't know how to fix it. I am supposed to compile my Polynomial.cpp with my professor's poly_check.o, but I get a segmentation fault error.
This is my Polynomial.h:
#ifndef POLYNOMIAL_H
#define POLYNOMIAL_H
#include <iostream>
using namespace std;
class Polynomial {
private:
double *coefficients;
int size;
public:
Polynomial();
Polynomial(double c[], int size);
Polynomial(const Polynomial &poly);
~Polynomial();
void set(double c[], int size);
inline int getDegree() const {
return size - 1;
}
double f(double x)const;
bool operator== (const Polynomial &poly)const;
Polynomial operator+ (const Polynomial &poly)const;
friend ostream & operator << (ostream &out, const
Polynomial &poly);
friend istream & operator >> (istream &in, Polynomial
&poly);
};
#endif
This is my Polynomial.cpp:
#include "Polynomial.h"
#include <iostream>
#include <cmath>
using namespace std;
Polynomial::Polynomial() {
size = 0;
coefficients = NULL;
}
Polynomial::Polynomial(double c[], int size) {
this->size = size;
coefficients = new double[size];
for (int i = 0; i < size; i++) {
coefficients[i] = c[i];
}
}
Polynomial::Polynomial(const Polynomial &poly) {
if (coefficients != NULL)
delete coefficients;
this->size = poly.size;
coefficients = new double[size];
for (int i = 0; i < size; i++)
coefficients[i] = poly.coefficients[i];
}
Polynomial::~Polynomial() {
if (coefficients != NULL)
delete coefficients;
}
void Polynomial::set(double c[], int size) {
this->size = size;
if (coefficients != NULL)
delete coefficients;
coefficients = new double[size];
for (int i = 0; i < size; i++)
coefficients[i] = c[i];
}
double Polynomial::f(double x)const {
double value = 0.0;
for (int i = 0; i < size; i++) {
value += (coefficients[i] * pow(x, i));
}
return value;
}
bool Polynomial::operator== (const Polynomial &poly)const {
if (this->size != poly.size)
return false;
for (int i = 0; i < size; i++) {
if (poly.coefficients[i] != coefficients[i])
return false;
}
return true;
}
Polynomial Polynomial::operator+ (const Polynomial &poly)const {
int maxSize = size;
if (poly.size > maxSize)
maxSize = poly.size;
double sum[maxSize] = {0.0};
for (int i = 0; i < size; i++) {
sum[i] = coefficients[i];
}
for (int i = 0; i < poly.size; i++) {
sum[i] += poly.coefficients[i];
}
Polynomial sumP(sum, maxSize);
return sumP;
}
ostream &operator << (ostream &out, const Polynomial &poly) {
for (int i = poly.size - 1; i >= 0; i--) {
if (i != poly.size - 1) {
if (poly.coefficients[i] >= 0)
out << " + ";
else
out << " - ";
}
out << poly.coefficients[i];
if (i == 0)
continue;
if (i == 1)
out << "x";
else
out << "x^" << i;
}
return out;
}
istream &operator >> (istream &in, Polynomial &poly) {
int degree;
in >> degree;
double c[100];
int size = 0;
while (in >> c[size]) {
size++;
if ((size-1) == degree)
break;
}
poly.set(c, size);
return in;
}
This is my poly_test.cpp:
#include "Polynomial.h"
#include <iostream>
using namespace std;
int main(void) {
double c1[] = {0, 1, 2, 3, 4};
double c2[] = {0, 1, 2, 3, 4, 5, 6};
Polynomial p1(c1, 5);
Polynomial p2(c2, 7);
Polynomial p3;
cout << "Enter p3: ";
cin >> p3;
cout << "p1: ";
cout << p1 << endl;
cout << "p2: ";
cout << p2 << endl;
cout << "p3: ";
cout << p3 << endl;
Polynomial p4;
p4 = p1 + p2;
cout << "p4 = p1 + p2, p4: ";
cout << p4 << endl;
double value = p1.f(2);
cout << "Evaluating p1 at x = 2, p1 = ";
cout << value << endl;
Polynomial p6(c1, 5);
cout << "p6: ";
cout << p6 << endl;
if (p6 == p1) {
cout << "p6 and p1 are equal. Equality test passed" <<
endl;
}
else {
cout << "Equality test failed" << endl;
}
return 0;
}
This is the error that I am getting:
segmentation fault error
In general, you should test your own code as you develop it. Don't write this much code and then plug it into a test function; it will fail, and the process of debugging it will be long and discouraging.
The specific problem (or one of them) is that you neglected to implement operator=. Are you familiar with shallow copies and deep copies? The default copy constructor is a shallow copier, so that two instances of Polynomial wind up with pointers to the same array. Then when they die, they both try to delete it.
I'm a newbie to c++ programming (and programming in generally, actually), and I'm having some issues with a copy constructor in a c++ program that is supposed to demonstrate matrix addition.
I don't think my program is ever reaching the copy constructor, but I have no idea why. I understand why I should expect this to not work if I had not defined a copy constructor, since the destructor would have deleted the data that matrix result points to. But, I have defined a copy constructor. Where have I gone wrong?
Help is greatly appreciated!
My code is as follows:
#include<iostream>
#include<string>
#include<stdlib.h> // for c style exit
using namespace std;
class matrix
{
private:
double* mdata;
int rows, columns;
public:
// Declare the << operator as a friend of the class.
friend ostream& operator<<(ostream&, const matrix&);
// Define the default constructor.
matrix() : mdata(0), rows(0), columns(0) {}
// Define the parameterized constructor.
matrix(int numberOfRows, int numberOfColumns) : mdata(new double[numberOfColumns*numberOfColumns]), rows(numberOfRows), columns(numberOfColumns) {
for (int i{ 0 }; i <= numberOfColumns*numberOfRows; i++){
mdata[i] = 0;
}
}
// Define the copy constructor.
matrix(const matrix& matr) {
cout << endl << "Reached copy constructor." << endl;
rows = matr.getrows();
columns = matr.getcols();
mdata = 0;
if (matr.mdata){
mdata = new double[(matr.getrows())*(matr.getcols())];
for (int i{ 0 }; i <= rows*columns ; i++){
mdata[i] = matr.mdata[i];
cout << mdata[i] << endl;
}
}
else {
mdata = 0;
}
}
// Define the destructor.
~matrix() {
cout << "Destructor called on " << endl << *this;
delete[] mdata;
}
// Return the number of rows.
int getrows() const { return rows; }
// Return the number of columns.
int getcols() const { return columns; }
// Return the position in the array of element (m,n).
int index(int m, int n) const {
if (m>0 && m <= rows && n>0 && n <= columns) return (n - 1) + (m - 1)*columns;
else {
cout << "Error: out of range. Press any key to exit." << endl;
// For holding the program before exit.
exit(1);
}
}
// Allows array elements to be accessed with bracket notation.
double& operator()(int m, int n) const { return mdata[index(m, n)]; }
matrix& operator+(const matrix&) const;
// A function for edditing matrix elements
void setValue(int m, int n, double value) {
mdata[index(m, n)] = value;
}
};
// Define the << operator for printing matrices. This is a friend of the class.
ostream& operator<<(ostream &os, const matrix &mat){
// Deals with case of matrix with zero size.
if (mat.rows == 0 && mat.columns == 0){
cout << "This matrix is has no size." << endl;
}
// If the matrix has non-zero size,
else {
// For each row in the matrix,
for (int i{ 1 }; i <= mat.rows; i++) {
cout << "[";
// For each column in that row
for (int j{ 1 }; j <= mat.columns; j++){
// Print the element, followed by a comma.
if (j < mat.columns){
cout << mat(i, j) << ", ";
}
// Ensures no comma is placed after last elemet in row.
else{
cout << mat(i, j);
}
}
os << "]" << endl;
}
}
return os;
}
// The addition operator
matrix& matrix::operator+(const matrix& mat) const {
matrix result(rows, columns);
// If the matrix dimensions are different,
if (rows != mat.getrows() || columns != mat.getcols()){
cout << "Cannot add two matrices with differing dimensions." << endl;
string exitStr;
cout << "Enter any key to exit." << endl;
cin >> exitStr;
// Exit the program
exit(1);
}
// Otherwise, create a matrix with the appropriate dimensions
else{
// For each element in result
for (int k{ 1 }; k <= result.getrows(); ++k){
for (int l{ 1 }; l <= result.getcols(); ++l){
// That element is the sum of the corresponding elements in the two input matrices.
result.setValue(l,k,(mat(l, k) + (*this)(l, k)));
}
}
}
return result;
}
// Main program
int main()
{
// Demonstrate default constructor
matrix a1;
cout << "Matrix a1: ";
cout << a1;
// Demonstrate parameterized constructor
const int m(2), n(2);
matrix a2(m, n);
// Set values for a2
a2.setValue(1, 1, 1);
a2.setValue(2, 2, 1);
a2.setValue(1, 2, 1);
a2.setValue(2, 1, 1);
// Print matrix a2
cout << "a2 = " << endl << a2 << endl;
// Demonstrate parameterized constructor
matrix a3(m, n);
// Set values for a3
a3.setValue(1, 1, 2);
a3.setValue(2, 2, 2);
a3.setValue(1, 2, 2);
a3.setValue(2, 1, 2);
// Print matrix a3
cout << "a3 = " << endl << a3 << endl;
// Create matrix a4
matrix a4(a2 + a3);
cout << endl << "The sum of a2 and a3 is: " << endl << a4;
// For halting the program.
int x;
cin >> x;
return 0;
}
for (int i{ 0 }; i <= numberOfColumns*numberOfRows; i++)
should be
for (int i{ 0 }; i < numberOfColumns*numberOfRows; i++)
you are looping through N+1 instead of N
I'm trying to figure out why my program fails when I run. So far when I run my program it fails on me. I debugged the error and it brings me to dbgdel.cpp. Line 32 " _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));". I've searched for the answer to no avail, but it has something to do with my memory leak?
Here is my header:
#include <iostream>
using namespace std;
namespace project
{
#ifndef MATRIX_H
#define MATRIX_H
typedef int* IntArrayPtr;
class Matrix
{
public:
friend ostream& operator<<(ostream& out, Matrix& object);
//friend istream& operator>>(istream& in, Matrix& theArray);
//Default Constructor
Matrix();
Matrix(int max_number_rows, int max_number_cols, int intial_value);
//Destructor
~Matrix();
//Copy Constructor
Matrix(const Matrix& right_side);
//Assignment Operator
Matrix& operator=(const Matrix& right_side);
void Clear();
int Rows();
int Columns();
bool GetCell(int x,int y, int& val);
bool SetCell(int x,int y, int val);
int getNumber(int r, int c);
//void Debug(ostream& out);
private:
int initialVal;
int rows;
int cols;
IntArrayPtr *m;
};
#endif
}
My implementation file:
#include <iostream>
#include "Matrix.h"
using namespace project;
using namespace std;
namespace project
{
Matrix::Matrix()
{
typedef int* IntArrayPtr;
IntArrayPtr *m = new IntArrayPtr[1];
for(int i = 0; i < 1; i++)
m[i] = new int[1];
for(int r = 0; r < 1; r++)
for(int c = 0; c < 1;c++)
m[r][c] = 0;
}
Matrix::Matrix(int max_number_rows, int max_number_cols, int initial_value)
{
initialVal = initial_value;
rows = max_number_rows;
cols = max_number_cols;
IntArrayPtr *m = new IntArrayPtr[rows];
for(int i = 0; i < rows; i++)
m[i] = new int[cols];
for(int r = 0; r < max_number_rows; r++)
for(int c = 0; c < max_number_cols;c++)
m[r][c] = initial_value;
}
Matrix::~Matrix()
{
for(int i = 0; i <= rows; i++)
delete [] m[i];
delete [] m;
}
void Matrix::Clear()
{
for(int r = 0; r < rows; r++)
for(int c = 0; c < cols;c++)
m[r][c] = initialVal;
}
int Matrix::Rows()
{
return rows;
}
int Matrix::Columns()
{
return cols;
}
bool Matrix::GetCell(int x,int y, int& val)
{
if(x < rows || y < cols)
return false;
else
{
val = m[x - 1][y - 1];
return true;
}
}
bool Matrix::SetCell(int x, int y, int val)
{
if(x < rows || y < cols)
return false;
else
{
m[x - 1][y - 1] = val;
return true;
}
}
int Matrix::getNumber(int r, int c)
{
return m[r][c];
}
ostream& operator<<(ostream& out, Matrix& object)
{
for(int r = 0; r < object.rows; r++)
{
for(int c = 0; c < object.cols; c++)
{
out << " " << object.m[r][c];
}
out << endl;
}
return out;
}
Matrix& Matrix::operator=(const Matrix& right_side)
{
if (this != &right_side)
{
rows = right_side.rows;
cols = right_side.cols;
delete[] m;
IntArrayPtr *m = new IntArrayPtr[rows];
for(int i = 0; i < rows; i++)
m[i] = new int[cols];
for(int r = 0; r < rows; r++)
for(int c = 0; c < cols;c++)
m[r][c] = right_side.initialVal;
}
return *this;
}
/*
void Matrix::Debug(ostream& out)
{
out << "Number of rows = " << rows << endl;
out << "Number of columns = " << cols << endl;
out << "Initializer = " << initialVal << endl;
out << "Current contents of the matrix: " << endl;
out << m << endl;
}
*/
/*
istream& operator >>(istream& in, Matrix& theArray)
{
in >>
}
void interfaceMatrix()
{
int userChoice, rows, columns, value;
cout << "Default matrix or custom(1 for default, 0 for custom): ";
cin >> userChoice;
if (userChoice == 1)
{
Matrix object;
return object;
}
else if(userChoice == 0)
{
cout << "Enter number of rows: ";
cin >> rows;
cout << "Enter number of columns: ";
cin >> columns;
cout << "Enter initial value of each element: ";
cin >> value;
if(rows <= 0 || columns <= 0)
{
cout << "Invalid input." << endl;
exit(1);
}
else
{
Matrix object(rows, columns, value);
return object;
}
}
else
{
cout << "Invalid choice." << endl;
exit(1);
}
}
*/
}
In my driver I just put Matrix test(2,2,2), so I can create a 2 x 2 array with initial value of 2 for each element. I get the above error.
You are allocating rows number of rows, but deallocating rows+1 number of rows.
Check the destructor. <= must be <.
Besides this there are a lot of other [potential] errors in your code:
you are setting the local m variable instead of setting the m data member of your class (that's why I have the convention to always precede data members by m_ to prevent this kind of confusion). This error appears both in the constructor and the assignment operator.
you use rows to allocate the matrix, but max_number_rows to initialize the matrix. Although it works correctly now, it may lead to errors if row is initialized differently later (e.g. if row is initialized with std::max(max_number_rows,1000). Your code in the assignment operator is better.
your if-test in GetCell and SetCell is incorrect. It should probably be >= instead of <
the assignment operator copies the size of the matrix, but assigns all cells an initialValue. This is not an assignment. This implementation might/will confuse the rest of the code.
the typedef of IntArrayPtr is unnecessary
two issues:
You are not allocating any value into the "m" member of your object, you are allocating into local variables named "m"
you are over deallocating by looping from i=0 to i <= rows, you want i=0 to i < rows
First off i know the multiplying part is wrong but i have some questions about the code.
1. When i am overloading my operator+ i print out the matrix using cout << *this then right after i return *this and when i do a+b on matix a and matix b it doesnt give me the same thing this is very confusing.
2. When i make matrix c down in my main i cant use my default constructor for some reason because when i go to set it = using my assignment operator overloaded function it gives me an error saying "expression must be a modifiable value. although using my constructor that sets the row and column numbers is the same as my default constructor using (0,0).
3. My assignment operator= function uses a copy constructor to make a new matrix using the values on the right hand side of the equal sign and when i print out c it doesn't give me anything
Any help would be great this is my hw for a algorithm class which i still need to do the algorithm for the multiplying matrices but i need to solve these issues first and im having a lot of trouble please help.
//Programmer: Eric Oudin
//Date: 10/21/2013
//Description: Working with matricies
#include <iostream>
using namespace std;
class matrixType
{
public:
friend ostream& operator<<(ostream&, const matrixType&);
const matrixType& operator*(const matrixType&);
matrixType& operator+(const matrixType&);
matrixType& operator-(const matrixType&);
const matrixType& operator=(const matrixType&);
void fillMatrix();
matrixType();
matrixType(int, int);
matrixType(const matrixType&);
~matrixType();
private:
int **matrix;
int rowSize;
int columnSize;
};
ostream& operator<< (ostream& osObject, const matrixType& matrix)
{
osObject << endl;
for (int i=0;i<matrix.rowSize;i++)
{
for (int j=0;j<matrix.columnSize;j++)
{
osObject << matrix.matrix[i][j] <<", ";
}
osObject << endl;
}
return osObject;
}
const matrixType& matrixType::operator=(const matrixType& matrixRight)
{
matrixType temp(matrixRight);
cout << temp;
return temp;
}
const matrixType& matrixType::operator*(const matrixType& matrixRight)
{
matrixType temp(rowSize*matrixRight.columnSize, columnSize*matrixRight.rowSize);
if(rowSize == matrixRight.columnSize)
{
for (int i=0;i<rowSize;i++)
{
for (int j=0;j<columnSize;j++)
{
temp.matrix[i][j] = matrix[i][j] * matrixRight.matrix[i][j];
}
}
}
else
{
cout << "Cannot multiply matricies that have different size rows from the others columns." << endl;
}
return temp;
}
matrixType& matrixType::operator+(const matrixType& matrixRight)
{
matrixType temp;
if(rowSize == matrixRight.rowSize && columnSize == matrixRight.columnSize)
{
temp.setRowsColumns(rowSize, columnSize);
for (int i=0;i<rowSize;i++)
{
for (int j=0;j<columnSize;j++)
{
temp.matrix[i][j] = matrix[i][j] + matrixRight.matrix[i][j];
}
}
}
else
{
cout << "Cannot add matricies that are different sizes." << endl;
}
return temp;
}
matrixType& matrixType::operator-(const matrixType& matrixRight)
{
matrixType temp(rowSize, columnSize);
if(rowSize == matrixRight.rowSize && columnSize == matrixRight.columnSize)
{
for (int i=0;i<rowSize;i++)
{
for (int j=0;j<columnSize;j++)
{
matrix[i][j] -= matrixRight.matrix[i][j];
}
}
}
else
{
cout << "Cannot subtract matricies that are different sizes." << endl;
}
return *this;
}
void matrixType::fillMatrix()
{
for (int i=0;i<rowSize;i++)
{
for (int j=0;j<columnSize;j++)
{
cout << "Enter the matix number at (" << i << "," << j << "):";
cin >> matrix[i][j];
}
}
}
matrixType::matrixType()
{
rowSize=0;
columnSize=0;
matrix = new int*[rowSize];
for (int i=0; i < rowSize; i++)
{
matrix[i] = new int[columnSize];
}
}
matrixType::matrixType(int setRows, int setColumns)
{
rowSize=setRows;
columnSize=setColumns;
matrix = new int*[rowSize];
for (int i=0; i < rowSize; i++)
{
matrix[i] = new int[columnSize];
}
}
matrixType::matrixType(const matrixType& otherMatrix)
{
rowSize=otherMatrix.rowSize;
columnSize=otherMatrix.columnSize;
matrix = new int*[rowSize];
for (int i = 0; i < rowSize; i++)
{
matrix[i]=new int[columnSize];
for (int j = 0; j < columnSize; j++)
{
matrix[i][j]=otherMatrix.matrix[i][j];
}
}
}
matrixType::~matrixType()
{
delete [] matrix;
}
int main()
{
matrixType a(2,2);
matrixType b(2,2);
matrixType c(0,0);
cout << "fill matrix a:"<< endl;;
a.fillMatrix();
cout << "fill matrix b:"<< endl;;
b.fillMatrix();
cout << a;
cout << b;
//c = a+b;
cout <<"matrix a + matrix b =" << a+b;
system("PAUSE");
return 0;
}
EDIT:
still having trouble with things not returning what i am telling it to return
This code doesn't do what you think it does:
for (int j = 0; j < columnSize; j++)
{
matrix[i]=new int[columnSize];
matrix[i][j]=otherMatrix.matrix[i][j];
}
It allocates a column, then copies the first value. Then it allocates another column (forgetting about the old column), and copies the second value. Then it allocates another column (forgetting about the old column again), and copies the third value.
I hope the problem is clear from that description alone.
Are you trying to use matrixType c();? That would declare a function. The correct syntax to use the default constructor would be matrixType c;
Your operator= doesn't actually assign anything. So c = a+b; calculates a+b but doesn't change c.
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:
const matrix operator+(const matrix &rhs) const {
matrix tmp = *this; // copy!
return (tmp += rhs); // potentially another copy
}
You have no copy c-tor and compiler will generate default, which does memberwise-copy, but if you have dynamically allocated resources in class - you should have your own copy c-tor, that do deep-copy.