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 ;
Related
yesterday our lecturer got us this code below without any meaningful explanation. We are struggling to understand how it works.
class Matrix {
static int mem;
int rows, cols;
int* ptr;
public:
Matrix(int l = 10, int k = 10) :rows(l), cols(k) {
ptr = new int[rows * cols];
mem += (rows * cols) * sizeof(int);
}
Matrix(const Matrix& x) :rows(x.rows), cols(x.cols) {
ptr = new int[rows * cols];
int* tmp = ptr; // HERE
mem += (rows * cols) * sizeof(int);
for (int i = 0; i < x.rows * x.cols; i++) {
ptr[i] = x.ptr[i];
}
}
~Matrix() {
mem -= (rows * cols) * sizeof(int);
delete[] ptr;
}
friend istream& operator>>(istream& input, Matrix& x) {
int* tmp = x.ptr;
for (int i = 0; i < x.rows; i++) {
for (int j = 0; j < x.cols; j++) {
input >> *tmp; tmp++;
}
}
return input;
}
friend ostream& operator<<(ostream& output, Matrix& x) {
int* tmp = x.ptr;
for (int i = 0; i < x.rows; i++) {
for (int j = 0; j < x.cols; j++) {
output << *tmp << " "; tmp++;
}
output << endl;
}
return output;
}
friend Matrix operator+(const Matrix& x, const Matrix& y) {
Matrix tmp(x.rows,x.cols);
if (x.rows != y.rows || x.cols != y.cols) {
return tmp;
}
else {
for (int i = 0; i < x.rows * x.cols; i++) {
tmp.ptr[i] = x.ptr[i] + y.ptr[i];
}
return tmp;
}
}
Matrix operator=(const Matrix& x) {
if (x.rows != x.cols) {
delete[] ptr;
rows = x.rows;
cols = x.cols;
ptr = new int[rows * cols];
mem += (rows * cols) * sizeof(int);
}
for (int i = 0; i < x.rows * x.cols; i++) {
ptr[i] = x.ptr[i];
}
return *this;
}
friend Matrix operator*(const Matrix& x, const Matrix& y) {...}
};
Based on this chunk of code we have to overload '*' operator that would multiply two matrices together (ex. C = A * B).
And when it's fairly easy to do with 2D arrays, I just can't wrap my head around the way it's working right now, so any help would be more than appreciated.
Thanks for your time!
So I'm trying to overload the operator + in a template class.
the code compiles and runs but crashes at the use of the operator +.
tried so many things, I think it's a syntax problem? any advice would be appreciated!
The operator = is overloaded and works.
Matrix.h
template <int row, int col, class T = int>
class Matrix
{
int rows;
int cols;
T** mat;
public:
Matrix(int defVal = 0) {
rows = row;
cols = col;
memory();
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
mat[i][j] = defVal;
}
~Matrix() {
del();
}
Matrix(const Matrix& other) {
*this = other;
}
const Matrix& operator=(const Matrix& other) {
if (&other != this)
{
rows = other.rows;
cols = other.cols;
del();
memory();
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
mat[i][j] = other.mat[i][j];
}
return *this;
}
friend ostream& operator<<(ostream& os, const Matrix& m) {
for (int i = 0; i < m.cols; i++)
{
for (int j = 0; j < m.rows; j++)
os << m.mat[i][j] << " ";
os << endl;
}
return os;
}
friend Matrix operator+(const Matrix& other, T num) {
Matrix temp = other;
for (int i = 0; i < temp.rows; i++)
for (int j = 0; j < temp.cols; j++)
temp.mat[i][j] += num;
return temp;
}
void memory(){
mat = new T * [rows];
for (int i = 0; i < rows; i++)
mat[i] = new T[cols];
}
void del(){
for (int i = 0; i < rows; i++)
delete[] mat[i];
delete[] mat;
}
};
main.cpp
int main() {
Matrix<4, 4> mat;
std::cout << mat << std::endl;
Matrix<4, 4> identity(1);
std::cout << identity + 3 << std::endl; //crashes here
return 0;
}
if you need other parts of the code let me know! Thanks in advance!
Your copy constructor and assignment looks suspicious, you del after changing rows and cols, without initialising anything.
I expect it should be
Matrix(const Matrix& other) : rows(0), cols(0), mat(nullptr) {
*this = other;
}
const Matrix& operator=(const Matrix& other) {
if (&other != this)
{
del(); // clean up first
rows = other.rows;
cols = other.cols;
memory();
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
mat[i][j] = other.mat[i][j];
}
return *this;
}
As an aside, I wouldn't use dynamic allocation here at all, and instead
template <typename T, size_t rows, size_t cols>
class Matrix
{
std::array<std::array<T, cols>, rows> mat;
public:
Matrix(T defVal = {}) {
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
mat[i][j] = defVal;
}
friend std::ostream& operator<<(std::ostream& os, const Matrix& m) {
for (int i = 0; i < cols; i++)
{
for (int j = 0; j < rows; j++)
os << m.mat[i][j] << " ";
os << std::endl;
}
return os;
}
friend Matrix operator+(Matrix other, T num) {
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
other.mat[i][j] += num;
return other;
}
// No need for any special members
};
i need some help. This is my first that hugh program in c++ (pointers are nightmare). I tried everything and i can't find what i did wrong.
class aghMatrix {
private:
T ** matrix;
int n;
int m;
public:
aghMatrix() : n(0), m(0) {};
aghMatrix(int _n, int _m);
aghMatrix(const aghMatrix& other);
~aghMatrix();
void setItem(int n, int m, T item);
void setItems (T * wsk);
void setItems(int r, int c ...);
void setAll();
void getALL();
bool couldbeadded(char * word, char sign);
bool equals (T first, T second);
T operator()(int a, int b);
aghMatrix<T> & operator+(const aghMatrix<T> & other);
aghMatrix<T> & operator*(const aghMatrix<T> & other);
aghMatrix<T> & operator= ( const aghMatrix<T> & other);
bool operator== (const aghMatrix<T> & other);
bool operator!= (const aghMatrix<T> & other);
};
Test :
char* cpt[] = {"to", "jest", "tablica", "wyrazow", "o", "rozmiarze", "jedenascie", "ktore", "beda", "elementami", "macierzy"};
aghMatrix<char*> cpm3(3, 1);
aghMatrix<char*> cpm4;
cpm3.setItems(cpt+3);
cpm4 = cpm3; // here my consol stop responding.
Constructors :
//default
aghMatrix() : n(0), m(0) {};
//with param
template <class T>
aghMatrix<T>::aghMatrix(int _n, int _m)
{
n = _n;
m = _m;
matrix = new T * [n];
for (int i = 0; i < n; i ++)
{
matrix[i] = new T[m];
}
}
setitems:
template <class T>
void aghMatrix<T>::setItems (T * wsk)
{
int licznik = 0;
for(int i = 0; i < n; i ++)
{
for (int j = 0; j < m; j ++)
{
matrix[i][j] = wsk[licznik];
licznik ++;
}
}
}
Operator= for char*
template <>
aghMatrix<char*> & aghMatrix<char*>::operator= ( const aghMatrix<char*> & other)
{
if ( & other != this)
{
if ( (other.n == n) && (other.m == m) && (this->matrix != 0))
{
for (int i = 0; i < n; i ++)
{
for (int j = 0; j < m; j ++)
{
for(int ii = 0; ii < strlen(other.matrix[i][j]); ii++)
{
matrix[i][j][ii] = other.matrix[i][j][ii];
}
}
}
}
else
{
if(this->matrix)
{
for (int i = 0; i < n; i ++)
{
for (int j = 0; j < m; j ++)
{
delete [] matrix[i][j];
}
delete [] matrix[i];
}
delete [] matrix;
n = 0;
m = 0;
matrix = NULL;
}
n = other.n;
m = other.m;
matrix = new char **[n];
for(int i = 0; i < n; i ++)
{
matrix[i] = new char*[m];
}
for(int i = 0; i < n; i ++)
{
for(int j = 0; j < m; j ++)
{
matrix[i][j] = new char[strlen(other.matrix[i][j])];
for(int ii = 0; ii < strlen(other.matrix[i][j]); ii ++)
{
matrix[i][j][ii] = other.matrix[i][j][ii];;
}
}
}
}
}
return *this;
}
I tried everything and still i'm getting this problem with console (it looks like i'm using somewhere uninitialized memory or sth). I cant solve this problem alone is alone can anybody help me?
EIDT: One more thing : The error shows when the program comes to end and after i change destructor :
Now looks like this :
template
aghMatrix<T>::~aghMatrix()
{
if (matrix)
{
for (int i = 0; i < n; i ++)
{
delete [] matrix[i];
}
delete [] matrix;
matrix = NULL;;
n = 0;
m = 0;
}
}
the previous version of destructor :
template <class T>
aghMatrix<T>::~aghMatrix()
{
if (matrix =! 0)
{
for (int i = 0; i < n; i ++)
{
delete [] matrix[i];
}
delete [] matrix;
matrix = 0;
}
}
maybe here is the reason of error?
EDIT:---------------------
I found the reason of my error here it is:
when i create
aghMatrix<char*> cpm3(3, 1);
cpm4 = cpm3; //destructor create a problem
but when i do something like this:
aghMatrix<char*>cpm3(3,2); //or somekind of other number than '1'
cpm4 = cpm3; // everything works fine
any ideas?
I'm trying to overload the + operator for a project that I'm doing but this keeps on happening. I think the reason is that the object I created is getting deleted when the operator is getting invoked. Not sure how to fix it though. Here's part of my code:
Matrix Matrix::operator+ (const Matrix& m) const
{
//something wrong here
Matrix sum(rows, cols);
for (int i = 0; i < cols; i++)
{
for (int j = 0; j < rows; j++)
{
sum.element[i][j] = this->element[i][j] + m.element[i][j];
}
}
return sum;
}
Additional Information
Matrix::Matrix(int r, int c)
{
rows = r;
cols = c;
element = new int *[c];
for (int i = 0; i < c; i++)
{
element[i] = new int[r];
}
for (int i = 0; i < cols; i++)
{
for (int j = 0; j < rows; j++)
{
element[i][j] = 0;
}
}
}
Matrix::Matrix(const Matrix& m)
{
this->element = m.element;
}
Matrix::~Matrix()
{
//freeing up the arrays
for (int i = 0; i < cols; i++)
{
delete[] element[i];
element[i] = NULL;
}
delete[] element;
element = NULL;
}
Matrix& Matrix::operator= (const Matrix& m)
{
//problem if rows and cols are longer in the new matrix
//need to create a temp matrix to expand to new one
for (int i = 0; i < cols; i++)
{
for (int j = 0; j < rows; j++)
{
this->element[i][j] = m.element[i][j];
}
}
return *this;
}
int* Matrix::operator[] (int n)
{
return element[n];
}
The specific error I am getting is:
Debug Assertion Failed!
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
In line 52 which I did this:
Matrix total = mat + m;
Where mat and m are both object matrices
I'm guessing the problem is caused by this:
Matrix::Matrix(const Matrix& m)
{
this->element = m.element;
}
That is an invalid copy constructor for two reasons. First, you're not initializing rows or cols. Second, you'll now have two Matrix objects pointing to the same memory - both of which will delete it on destruction:
{
Matrix m1(3, 5);
Matrix m2 = m1;
} // BOOM!
You need to do a deep copy here:
Matrix::Matrix(const Matrix& m)
: rows(m.rows), cols(m.cols)
{
element = new int *[cols];
for (int i = 0; i < cols; ++i) {
element[i] = new int[rows];
for (int j = 0; j < rows; ++j) {
element[i][j] = m.element[i][j];
}
}
}
To overload an "+" operator for const matrix, I use the "[]"
Matrix const operator+(const Matrix & mat1, const Matrix & mat2)
{
Matrix sum(mat1);
if (sum.height != mat2.height || sum.width != mat2.width)
cout << "Dimension error!";
else {
for (int i = 0; i < sum.height; i++)
for (int j = 0; j < sum.width; j++)
sum[i][j] = mat2[i][j];
}
return sum;
}
So, I define the overloading for []
(const int*)& operator[] (int i) const {
return (*this).ele[i + 1];
}
But the IDE report the error
"Error IntelliSense: a reference of type "const int *&" (not const-qualified) cannot be initialized with a value of type "int *"
How to solve this error? I have tried many times TAT.
And this is the entire code:
#define NULL 0
#include<iostream>
using namespace std;
class Matrix {
private:
int width, height;
int **ele;
public:
Matrix();
Matrix(int**);
Matrix(int, int);
Matrix(const Matrix&);
Matrix operator= (const Matrix&);
friend const Matrix operator+ (const Matrix&, const Matrix&);
friend const Matrix operator- (const Matrix&, const Matrix&);
(int*)& operator[] (int i) {
return (*this).ele[i + 1];
}
(const int*)& operator[] (int i) const {
return (*this).ele[i + 1];
}
};
Matrix::Matrix() {
width = 0; height = 0;
ele = NULL;
}
Matrix::Matrix(const Matrix& mat) {
Matrix(mat.height, mat.width);
for (int i = 0; i < height; i++)
for (int j = 0; j < width; j++) {
(*this)[i][j] = mat[i][j];
}
}
Matrix::Matrix(int** e) {
(*this).height = e[0][0];
(*this).width = e[0][1];
for (int i = 1; i < height; i++)
for (int j = 0; j < width; j++) {
(*this).ele[i][j] = e[i][j];
}
}
Matrix::Matrix(int height, int width) {
(*this).width = width;
(*this).height = height;
ele = new int*[height + 1];
ele[0] = new int[2];
ele[0][0] = height; ele[0][1] = width;
for (int i = 1; i < height + 1; i++)
{
ele[i] = new int[width];
}
for (int i = 1; i < height; i++)
for (int j = 0; j < width; j++) {
ele[i][j] = 0;
}
}
inline Matrix Matrix::operator=(const Matrix & mat)
{
Matrix tempMat(mat);
return tempMat;
}
Matrix const operator+(const Matrix & mat1, const Matrix & mat2)
{
Matrix sum(mat1);
if (sum.height != mat2.height || sum.width != mat2.width)
cout << "Dimension error!";
else {
for (int i = 0; i < sum.height; i++)
for (int j = 0; j < sum.width; j++)
sum[i][j] = mat2[i][j];
}
return sum;
}
Matrix const operator-(const Matrix & mat1, const Matrix & mat2)
{
Matrix diff(mat1);
if (diff.height != mat2.height || diff.width != mat2.width)
cout << "Demension error!";
else {
for (int i = 0; i < diff.height; i++)
for (int j = 0; j < diff.width; j++)
diff[i][j] = mat2[i][j];
}
return diff;
}
I have found your code compiled (g++ version 4.6.3) when removed parentheses from overloaded operators signature, like user remyabel said.
So try
int* operator[] (int i) {
return (*this).ele[i + 1];
}
const int* operator[] (int i) const {
return (*this).ele[i + 1];
}
instead of
(int*)& operator[] (int i) {
return (*this).ele[i + 1];
}
(const int*)& operator[] (int i) const {
return (*this).ele[i + 1];
}