I'm making simple matrix calculator for school project. I tried to use overloading operators but I have problem with operator "=". I checked it in debugger in Visual Studio and after assigning data from matrix A to matrix X all of data disappears. How should I repair this? Thank you in advance for your help and advice.
#include <iostream>
#include <vector>
#include <conio.h>
#include <stdlib.h>
using std::vector;
class Matrix {
private:
int rows, cols;
vector<vector<double>> matrix;
public:
Matrix(int r = 0, int c = 0) : rows(r), cols(c) {
std::vector<std::vector<double>> M(rows, std::vector<double>(cols));
matrix = M;
}
~Matrix() {}
// void operator+(const Matrix &rhs);
double get_rows() { return rows; }
double get_cols() { return cols; }
void set_matrix_value() {
std::cout << "Put values in your matrix\n";
for(int i = 0; i < matrix.size(); i++) {
for(int j = 0; j < matrix[i].size(); j++) {
// this->matrix[i][j] = int(_getch() - '0');
std::cin >> matrix[i][j];
}
}
}
void display_matrix() {
for(int i = 0; i < matrix.size(); i++) {
std::cout << "|";
for(int j = 0; j < matrix[i].size(); j++) {
std::cout << matrix[i][j];
if(j != matrix[i].size() - 1) {
std::cout << " ";
}
}
std::cout << "|\n";
}
}
Matrix operator=(const Matrix& M) {
rows = M.rows;
cols = M.cols;
Matrix new_matrix(rows, cols);
std::vector<std::vector<double>> m(rows, std::vector<double>(cols));
new_matrix.matrix = m;
for(int i = 0; i < m.size(); i++) {
for(int j = 0; j < m[i].size(); j++) {
new_matrix.matrix[i][j] = M.matrix[i][j];
}
}
return new_matrix;
}
Matrix operator+(const Matrix& m) {
if(rows != m.rows && cols != m.cols) {
std::cout << "Matrix sizes do not match. Write martix again.";
return (*this);
}
Matrix new_matrix(rows, cols);
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
new_matrix.matrix[i][j] = matrix[i][j] + m.matrix[i][j];
}
}
return new_matrix;
}
};
int main() {
// int k;
// int rows, cols;
Matrix X;
// std::cout << "Welcome in Matrix Mode!\n";
X.display_matrix();
Matrix A(3, 3);
A.set_matrix_value();
A.display_matrix();
X = A;
std::cout << X.get_rows() << " " << X.get_cols();
X.display_matrix();
}
Related
class Matrix
{
private:
int rows;
int cols;
int** Mat;
public:
Matrix(){}
Matrix(const int& rows, const int& cols):rows(rows),cols(cols)
{
Mat = new int* [cols];
for (int i = 0; i < rows; i++)
{
Mat[i] = new int[cols]();
}
}
Matrix operator +(const Matrix& other)const
{
Matrix temp(rows, cols);
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;
}
My question is regarding how I'd use shared_ptr and make_shared to replace int** Mat? and, after that, how do I use it in the constructor and operator+? It's a custom matrix class that should add matrices
#include <iostream>
#include <memory>
#include <cassert>
class Matrix {
private:
int rows;
int cols;
std::shared_ptr<std::shared_ptr<int>> Mat;
public:
Matrix() = default;
Matrix(const int& rows, const int& cols) : rows(rows), cols(cols)
{
Mat.reset(new std::shared_ptr<int>[rows], [](std::shared_ptr<int>* p) { delete[] p; });
for (int i = 0; i < rows; ++i)
{
Mat.get()[i].reset(new int[cols], [](int* p) { delete[] p; });
}
for (int i = 0; i < (*this).rows; ++i)
for (int j = 0; j < (*this).cols; ++j)
(*this)[i][j] = 0;
}
int* operator[](const int& index) const
{
return Mat.get()[index].get();
}
Matrix(const Matrix& other) : cols(other.cols), rows(other.rows)
{
Mat.reset(new std::shared_ptr<int>[rows], [](std::shared_ptr<int>* p) { delete[] p; });
for (int i = 0; i < rows; ++i)
{
Mat.get()[i].reset(new int[other.cols], [](int* p) { delete[] p; });
}
for (int i = 0; i < other.rows; i++)
for (int j = 0; j < other.cols; j++)
(*this)[i][j] = other[i][j];
}
Matrix& operator=(const Matrix& other)
{
if (Mat != other.Mat && cols == other.cols && rows == other.rows)
{
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
(*this)[i][j] = other[i][j];
return *this;
}
else
return *this;
}
Matrix operator+(const Matrix& other) const
{
Matrix temp(rows, cols);
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
temp[i][j] += other[i][j] + (*this)[i][j];
return temp;
}
friend std::ostream& operator<<(std::ostream& os, Matrix& m)
{
for (int i = 0; i < m.rows; ++i)
{
for (int j = 0; j < m.cols; ++j)
{
os << m[i][j] << " ";
}
os << std::endl;
}
return os;
}
};
int main()
{
Matrix a(2, 2);
a[0][0] = 1;
a[0][1] = 1;
std::cout << a << std::endl;
Matrix b(2, 2);
b[1][1] = 1;
b[1][0] = 1;
std::cout << b << std::endl;
b[1][0] = 9;
Matrix c(a);
c[0][0] = 6;
std::cout << c << std::endl;
Matrix d = b;
std::cout << d << std::endl;
Matrix e = a + b;
std::cout << e << std::endl;
}
I have solved it myself in the end :D
For my midterm assignment I am required to code a matrix with all details (like identify any size matrix, add (etc.) a number to matrix, add (etc.) two matrices together, transpose, determinant, print...).
I made a class called Matrix and wrote bunch of constructors and functions and overloaded operators.
#include <iostream>
#include <string>
#include <ctime>
#include<fstream>
#include<cstdlib>
#include<iomanip>
#include <cmath>
using namespace std;
class Matrix {
private:
int row;
int column;
int value;
int** matrix;
public:
Matrix(int ro, int col, int val);
Matrix(int ro, int col, char type);
~Matrix();
void print();
void resize(int ro , int col);
void operator=(const Matrix& other);
Matrix operator+(int num)const;
};
Matrix::Matrix(int ro=10, int col=10, int val=0)
:row(ro), column(col), value(val)
{
if (row <= 0 || column <= 0) {
cout << "invalid row or column value";
}
else{
matrix = new int* [row];
for (int i = 0; i < row; i++) {
matrix[i] = new int[column];
}
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
matrix[i][j] = value;
}
}
}
}
Matrix::Matrix(int ro, int col, char type)
:row(ro), column(col)
{
if (row <= 0 || column <= 0) {
cout << "invalid row or column value";
}
else {
matrix = new int* [row];
for (int i = 0; i < row; i++) {
matrix[i] = new int[column];
}
if (type == 'e'){
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
if (i == j) {
value = 1;
matrix[i][j] = value;
}
else {
value = 0;
matrix[i][j] = value;
}
}
}
}
srand(time(NULL));
if (type == 'r') {
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
value = rand() % 256;
matrix[i][j] =value;
}
}
}
}
}
void Matrix::operator=(const Matrix& other) {
this->resize(other.row, other.column);
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
matrix[i][j] = other.matrix[i][j]; // this line throw exception:Exception thrown at 0x00A7BCF2 in matrix.exe: 0xC0000005: Access violation reading location 0xDDDDDDDD.
}
}
}
Matrix Matrix::operator+(int num) const {
Matrix model(row, column);
for (int i = 0; i < model.row; i++) {
for (int j = 0; j < model.column; j++) {
model.matrix[i][j] = matrix[i][j] + num;
}
}
return model;
}
void Matrix::print() {
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
cout<< setw(6) << matrix[i][j]<< " " ;
}
cout << endl;
}
}
Matrix::~Matrix() {
for (int i = 0; i < row; i++) {
delete[] matrix[i];
}
delete[] matrix;
}
void Matrix::resize(int ro, int col){
int** copymatrix;
copymatrix = matrix;
matrix = new int* [ro];
for (int i = 0; i < ro; i++) {
matrix[i] = new int[col];
}
for (int i = 0; i < ro; i++) {
for (int j = 0; j < col; j++) {
if (i >= row || j >= column) {
matrix[i][j] = 0;
}
else {
matrix[i][j] = copymatrix[i][j];
}
}
}
row = ro;
column = col;
}
int main() {
Matrix mat1(3, 6, 2);
cout << endl;
mat1 = mat1 + 5;
mat1.print();
}
I also tried this but gives me the same error
Matrix Matrix::operator=(const Matrix& other) {
Matrix model(other.row, other.column);
for (int i = 0; i < model.row; i++) {
for (int j = 0; j < model.column; j++) {
model.matrix[i][j] = other.matrix[i][j]; //exception
}
}
return model;
}
I actually have problems with operators overloading. As I write in the main function when I use operator+ overloading it returns a matrix and after that it comes to operator= overloading and there is the problem as it returns the matrix and comes to operator= it gives me the error Exception thrown at 0x00CEBCDB in matrix.exe: 0xC0000005: Access violation reading location 0xDDDDDDDD. I think I know why but I don't know how to solve it.
This code works in CodeBlocks 17.12. It throws the error in Visual Studio 2019 (v142).
Your assignment operator doesn't assign new memory for the matrix:
void Matrix::operator=(const Matrix& other)
{
this->resize(other.row, other.column);
for (int i = 0; i < row; i++)
for (int j = 0; j < column; j++)
{
matrix[i][j] = other.matrix[i][j];
}
}
So, after it, you'll be accessing memory through an uninitialized pointer.
You need assignment operators, constructors that correctly allocate memory for your matrices. You need matching destructors, too. Look up "rule of 3".
Matrix& Matrix::operator=(const Matrix& other) {
if (this == &other) {
return *this;
}
this->resize(other.row, other.column);
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
matrix[i][j] = other.matrix[i][j];
}
}
return *this;
}
Matrix Matrix::operator+(int num) const {
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
this->matrix[i][j] += num;
}
}
return *this;
}
When Function return a matrix by finishing the scope Destructor get called and after we call assignment operator overloading on it, it can't reach the member of that matrix because it already get deleted by Destructor so it throws a exception.
I wrote this before but it did not work until i realize that we should put (&) for (=) operator if we want use this operators overloading one after the other. so now it's working well
So I have decided to restart my program everything except the + operator is working now. I get the read access violation exception
Header File
#pragma once
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
using namespace std;
class MatrixType
{
private:
int **matrix;
int row;
int col;
public:
void setElement(int r, int c, int newvalue);
void display();
const MatrixType& operator=(const MatrixType& mat);
MatrixType operator+(const MatrixType& mat) const;
friend std::ostream & operator << (std::ostream & out, const MatrixType & mat);
MatrixType(int r, int c);
MatrixType(string fileName);
MatrixType(const MatrixType& mat);
MatrixType();
~MatrixType();
};
Implementation File
#include "matrixType.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
using namespace std;
void MatrixType::setElement(int r, int c, int newvalue)
{
matrix[r][c] = newvalue;
}
void MatrixType::display()
{
for (int i = 0; i < row; i++)
{
for (int r = 0; r < col; r++)
cout << matrix[i][r] << " ";
cout << endl;
}
cout << endl;
}
const MatrixType& MatrixType::operator=(const MatrixType& mat)
{
if (row != mat.row)
{
cout << "The matrixes are not identical" << endl;
return *this;
}
for (int i = 0; i < row; i++)
{
for (int r = 0; r < col; r++)
{
matrix[i][r] = mat.matrix[i][r];
}
}
return *this;
}
MatrixType MatrixType::operator+(const MatrixType& mat) const
{
MatrixType tempMatrix;
if (row != mat.row)
{
cout << "The matrixes are not identical can not be added together" << endl;
return *this;
}
else
{
for (int i = 0; i < mat.row; i++)
{
for (int r = 0; r < mat.col; r++)
{
tempMatrix.matrix[i][r] = mat.matrix[i][r] + matrix[i][r];
}
}
return tempMatrix;
}
}
std::ostream & operator << (std::ostream & out, const MatrixType & mat)
{
for (int i = 0; i < mat.row; i++) {
for (int j = 0; j < mat.col; j++) {
out << mat.matrix[i][j] << " ";
}
out << std::endl;
}
return out;
}
MatrixType::MatrixType(int r, int c)
{
matrix = new int*[r];
for (int i = 0; i < r; i++)
{
matrix[i] = new int[c];
}
row = r;
col = c;
for (int i = 0; i < row; i++)
{
for (int s = 0; s < col; s++)
{
matrix[i][s] = 0;
}
}
}
MatrixType::MatrixType(string fileName)
{
int r;
int c;
int z;
ifstream myFile;
myFile.open(fileName);
myFile >> r;
myFile >> c;
matrix = new int*[r];
for (int i = 0; i < r; i++)
{
matrix[i] = new int[c];
}
for (int i = 0; i < r; i++)
{
for (int s = 0; s < c; s++)
{
myFile >> z;
matrix[i][s] = z;
}
}
row = r;
col = c;
myFile.close();
}
MatrixType::MatrixType(const MatrixType& mat)
{
row = mat.row;
col = mat.col;
matrix = new int*[row];
for (int i = 0; i < row; i++)
{
matrix[i] = new int[col];
}
for (int i = 0; i < row; i++)
{
for (int s = 0; s < col; s++)
{
matrix[i][s] = mat.matrix[i][s];
}
}
}
MatrixType::MatrixType()
{
}
MatrixType::~MatrixType()
{
for (int i = 0; i < row; i++)
{
delete[] matrix[i];
}
delete[] matrix;
}
Source Code
#include "MatrixType.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
using namespace std;
int main()
{
MatrixType M1("matrixfile1.txt");
MatrixType M2("matrixfile2.txt");
MatrixType M3("matrixfile3.txt");
cout << "Matrix 1:" << endl << M1 << endl << endl;
cout << "Matrix 2:" << endl << M2 << endl << endl;
cout << "Matrix 3:" << endl << M3 << endl << endl;
MatrixType M4 = M1 + M3;
return 0;
}
So basically the goal is to check to see if the matrixes are identical otherwise you should just see a print the matrixes are not the same size.
The matrixfile1,2,3 that look like
3 3
1 1 1
1 1 1
1 1 1
That show the dimensions of the array and their elements. My question is what I could do to make my operator function work better as it is currently not able to add the matrixs together yet. Everything else though once again works its just the operator that gets a read access violation.
MatrixType::MatrixType()
{
}
This doesn't initialize the members row, col, or matrix at all, so it's undefined behavior to attempt to use the current values of any of them.
Since you haven't provided a way to change the dimensions of a MatrixType at all, even using operator=, there doesn't seem to be any good use of a default constructor, and probably the MatrixType() default constructor shouldn't exist at all.
MatrixType MatrixType::operator+(const MatrixType& mat) const
{
MatrixType tempMatrix;
Your operator+ starts out by initializing tempMatrix using the default constructor. So the dimensions of tempMatrix are...?
This is supposed to be my HW in OOP course. SO i asked to create matrix class. Code works fine - all methods and new operands works fine BUT when my D`tor is empty and when i write there code to free memory i get this error. Thanks for help
int main()
{
MyMatrix m1(3, 3);
MyMatrix m2(3, 3);
MyMatrix res(3, 3);
m1.Set();
m2.Set();
cout << m1;
cout << m2;
res = m1 + m2;
cout << res;
}
CPP
MyMatrix::MyMatrix(int row, int col) // C`tor with specific data
{
n = row;
m = col;
matrix = new int* [n]; // Memory allocation for rows
for (int i = 0; i < n; i++)
{
matrix[i] = new int[m]; // Memory Allocation for columns
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
matrix[i][j] = 0;
}
}
}
MyMatrix::~MyMatrix() // Default d`tor
{
for (int i = 0; i < n; i++)
{
delete[] matrix[i];
}
delete[] matrix;
}
void MyMatrix::Set()
{
cout << "Enter new row" << endl;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
cin >> matrix[i][j];
}
if (i != (n - 1))
{
cout << "Enter new row" << endl;
}
}
}
ostream& operator<<(ostream& out, const MyMatrix& matrix)
{
for (int i = 0; i < matrix.n; i++)
{
//run in loop on every column.
for (int j = 0; j < matrix.m; j++)
//print value with a space.
out << matrix.matrix[i][j] << "t";
//at the end of every row jump line.
out << endl;
}
out << endl;
return out;
}
MyMatrix& MyMatrix::operator= (const MyMatrix& mat1)
{
n = mat1.n;
m = mat1.m;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
matrix[i][j] = mat1.matrix[i][j];
}
}
return *this;
}
const MyMatrix MyMatrix::operator+(const MyMatrix& mat1) const
{
MyMatrix temp(n, m);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
temp.matrix[i][j] = matrix[i][j] + mat1.matrix[i][j];
}
}
return temp;
}
H file
class MyMatrix
{
private:
int **matrix;
int n, m;
public:
MyMatrix(int a, int b);
~MyMatrix();
void Set();
const MyMatrix operator+ (const MyMatrix& mat1) const;
MyMatrix& operator= (const MyMatrix& mat1);
friend ostream& operator<<(ostream& out, const MyMatrix& matrix);
};
I'm trying to implement a matrix class and overloading the + and = operators.
The problem is I'm getting weird output when I add two matrices as in this picture.
adding two matrices output console
#include <iostream>
#include <iomanip>
using namespace std;
class Matrix
{
int **p, m, n;
public:
Matrix(int row, int col)
{
m = row;
n = col;
p = new int*[m];
for (int i = 0; i < m; i++)
p[i] = new int[n];
}
Matrix (Matrix & x)
{
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
p[i][j]=x.p[i][j];
}
}
}
~Matrix()
{
for (int i = 0; i < m; i++)
delete [] p[i];
delete [] p;
}
void accept()
{
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
cin >> p[i][j];
}
}
}
void display()
{
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
cout << setw(10)<<left <<p[i][j] <<" | ";
}
cout << "\n--------------------------------------"<<endl;
}
}
Matrix& operator +(const Matrix & m2)
{
Matrix r(m, n);
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
r.p[i][j] = p[i][j] + m2.p[i][j];
}
}
return r;
}
Matrix& operator= (const Matrix & eq)
{
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
p[i][j]=eq.p[i][j];
}
}
return *this;
}
friend Matrix operator * (Matrix, Matrix);
};
Matrix operator* (Matrix a , Matrix b)
{
Matrix B(1,1);
if(a.n == b.m)
{
Matrix T(a.m, b.n);
for(int i = 0; i < a.m; i++)
{
for(int k = 0; k < b.n; k++)
{
T.p[i][k] = 0;
for(int j = 0; j < a.n; j++)
{
T.p[i][k]+= a.p[i][j] * b.p[j][k];
}
}
}
B = T;
}
return B;
}
int main()
{
cout << "Enter Matrix 1 (3x2):"<<endl;
Matrix m1(3,2);
m1.accept();
m1.display();
cout << "Enter Matrix 2 (3x2):"<<endl;
Matrix m2(3,2);
m2.accept();
m2.display();
Matrix m3(3,2);
m3=m1+m2;
cout <<endl<< "matrix1 + matix2 is:\n "<<endl;
m3.display();
}
Any ideas how to fix that? I would be grateful for your help and advices with improving it because probably there will be some mistakes.
I use CodeBlocks IDE.
The problem is that your operator + returns a local variable Matrix as a reference; this is undefined behavior. It should be returned by value, not by reference.
Make sure that your Matrix class has a copy constructor that takes a const input, i.e.
Matrix (const Matrix & x)
and that it initializes the array before writing into it. Move the initialization code (the two loops with allocation) into a separate private function, and call it from the default constructor and from the copy constructor.