I've got problem with my Matrix program.
There are my errors:
24 bytes in 1 blocks are indirectly lost in loss record 1 of 7
==5334== at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5334== by 0x402B26: Matrix::CountingReference::CountingReference(int, int) (in /home/detek/Pulpit/Matrix/main)
==5334== by 0x401725: Matrix::Matrix(int, int) (in /home/detek/Pulpit/Matrix/main)
==5334== by 0x401305: main (in /home/detek/Pulpit/Matrix/main)
==5334==
==5334== 24 bytes in 1 blocks are indirectly lost in loss record 2 of 7
==5334== at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5334== by 0x402B26: Matrix::CountingReference::CountingReference(int, int) (in /home/detek/Pulpit/Matrix/main)
==5334== by 0x401725: Matrix::Matrix(int, int) (in /home/detek/Pulpit/Matrix/main)
==5334== by 0x40187D: Matrix::operator+(Matrix const&) (in /home/detek/Pulpit/Matrix/main)
==5334== by 0x40144E: main (in /home/detek/Pulpit/Matrix/main)
==5334==
==5334== 72 bytes in 3 blocks are indirectly lost in loss record 3 of 7
==5334== at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5334== by 0x402B7D: Matrix::CountingReference::CountingReference(int, int) (in /home/detek/Pulpit/Matrix/main)
==5334== by 0x401725: Matrix::Matrix(int, int) (in /home/detek/Pulpit/Matrix/main)
==5334== by 0x401305: main (in /home/detek/Pulpit/Matrix/main)
==5334==
==5334== 72 bytes in 3 blocks are indirectly lost in loss record 4 of 7
==5334== at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5334== by 0x402B7D: Matrix::CountingReference::CountingReference(int, int) (in /home/detek/Pulpit/Matrix/main)
==5334== by 0x401725: Matrix::Matrix(int, int) (in /home/detek/Pulpit/Matrix/main)
==5334== by 0x40187D: Matrix::operator+(Matrix const&) (in /home/detek/Pulpit/Matrix/main)
==5334== by 0x40144E: main (in /home/detek/Pulpit/Matrix/main)
==5334==
==5334== 120 (24 direct, 96 indirect) bytes in 1 blocks are definitely lost in loss record 5 of 7
==5334== at 0x4C2E0EF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5334== by 0x401712: Matrix::Matrix(int, int) (in /home/detek/Pulpit/Matrix/main)
==5334== by 0x401305: main (in /home/detek/Pulpit/Matrix/main)
==5334==
==5334== 120 (24 direct, 96 indirect) bytes in 1 blocks are definitely lost in loss record 6 of 7
==5334== at 0x4C2E0EF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5334== by 0x401712: Matrix::Matrix(int, int) (in /home/detek/Pulpit/Matrix/main)
==5334== by 0x40187D: Matrix::operator+(Matrix const&) (in /home/detek/Pulpit/Matrix/main)
==5334== by 0x40144E: main (in /home/detek/Pulpit/Matrix/main)
And my code is here:
It's Matrix.cpp
#include <iostream>
#include <cstdlib>
#include <fstream>
#include <ctime>
#include "Matrix.h"
using namespace std;
ostream& operator<<(ostream& o,const Matrix& Object)
{
for(int i=0;i<Object.dane->wiersz;i++)
{
for(int j=0;j<Object.dane->kolumna;j++)
{
o<<Object.dane->wsk[i][j]<<" ";
}
o<<endl;
}
return o;
}
Matrix::Matrix()
{
dane=new CountingReference();
}
Matrix::Matrix(int wiersz, int col)
{
dane=new CountingReference(wiersz,col);
}
Matrix::Matrix(const Matrix& Object)
{
Object.dane->countingReference++;
dane=Object.dane;
}
Matrix::~Matrix()
{
if(dane->countingReference==-1)
{
delete dane;
}
}
int Matrix::readref()
{
return this->dane->countingReference;
}
Matrix& Matrix::operator=(const Matrix& Object)
{
Object.dane->countingReference++;
if(dane->countingReference==0)
{
delete dane;
}
dane=Object.dane;
return *this;
}
Matrix Matrix::operator+(const Matrix& Object) throw(string)
{
Matrix A(dane->wiersz,dane->kolumna);
if(dane->wiersz!=Object.dane->wiersz || dane->kolumna!=Object.dane->kolumna)
{
string wyjatek = "Nie sa rowne.";
throw wyjatek;
}
else{
int i,j;
for(i=0; i<dane->wiersz;i++)
{
for(j=0; j<dane->kolumna; j++)
{
A.dane->wsk[i][j]=dane->wsk[i][j]+Object.dane->wsk[i][j];
}
}
}
return A;
}
Matrix Matrix::operator-(const Matrix& Object) throw(string)
{
Matrix A(dane->wiersz,dane->kolumna);
if(dane->wiersz!=Object.dane->wiersz || dane->kolumna!=Object.dane->kolumna)
{
string wyjatek = "Nie sa rowne.";
throw wyjatek;
}
else{
for(int i=0;i<dane->wiersz;i++)
{
for(int j=0;j<dane->kolumna;j++)
{
A.dane->wsk[i][j]=dane->wsk[i][j]-Object.dane->wsk[i][j];
}
}
}
return A;
}
Matrix Matrix::operator*(const Matrix& Object) throw(string)
{
double temp=0;
Matrix A(dane->wiersz,dane->kolumna);
if(dane->kolumna!=Object.dane->wiersz)
{
string wyjatek = "Nie sa rowne";
throw wyjatek;
}
else{
for(int i=0;i<dane->wiersz;i++)
{
for(int j=0;j<Object.dane->kolumna;j++)
{
for(int k=0;k<dane->kolumna;k++)
{
temp+=dane->wsk[i][j]*Object.dane->wsk[j][k];
}
A.dane->wsk[i][j]=temp;
}
}
}
return A;
}
Matrix Matrix::operator+=(const Matrix& Object) throw(string)
{
if(dane->wiersz!=Object.dane->wiersz || dane->kolumna!=Object.dane->kolumna)
{
string wyjatek = "Nie sa rowne.";
throw wyjatek;
}
else{
dane=dane->detach();
for(int i=0;i<dane->wiersz;i++)
{
for(int j=0;j<dane->kolumna;j++)
{
dane->wsk[i][j]+=Object.dane->wsk[i][j];
}
}
}
return *this;
}
Matrix& Matrix::operator-=(const Matrix& Object) throw(string)
{
if(dane->wiersz!=Object.dane->wiersz || dane->kolumna!=Object.dane->kolumna)
{
string wyjatek = "Nie sa rowne.";
throw wyjatek;
}
else{
dane=dane->detach();
for(int i=0;i<dane->wiersz;i++)
{
for(int j=0;j<dane->kolumna;j++)
{
dane->wsk[i][j]-=Object.dane->wsk[i][j];
}
}
}
return *this;
}
Matrix& Matrix::operator*=(const Matrix& Object) throw(string)
{
if(dane->kolumna!=Object.dane->wiersz)
{
string wyjatek = "Nie sa rowne.";
throw wyjatek;
}
else
{
int m=0,n=0;
double temp=0;
m=dane->wiersz;
n=Object.dane->kolumna;
Matrix A(m,n);
for(int i=0;i<dane->wiersz;i++)
{
for(int j=0;j<Object.dane->kolumna;j++)
{
for(int k=0;k<dane->kolumna;k++)
{
temp+=dane->wsk[i][k]*Object.dane->wsk[k][j];
}
A.dane->wsk[i][j] = temp;
temp=0;
}
}
dane=dane->detach();
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
dane->wsk[i][j]=A.dane->wsk[i][j];
}
}
}
return *this;
}
Matrix& Matrix::LoadFromFile(const char *string)
{
int m=0,n=0;
ifstream inFile;
inFile.open(string);
if(inFile.good())
{
inFile>>m;
inFile>>n;
dane=dane->detach();
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
inFile>>dane->wsk[i][j];
}
}
inFile.close();
}
return *this;
}
double Matrix::read( int i, int j) const
{
return dane->wsk[i-1][j-1];
}
void Matrix::write(int i, int j, const double x)
{
dane = dane->detach();
dane->wsk[i-1][j-1] = x;
}
bool Matrix::operator == (const Matrix& Object)
{
int i,j;
for(i=0;i<dane->wiersz;i++)
{
for(j=0;j<dane->kolumna;j++)
{
if(dane->wsk[i][j]!=Object.dane->wsk[i][j])
{
return false;
}
}
}
return true;
}
Matrix& Random(Matrix& Object)
{
for(int i=0;i<Object.dane->wiersz;i++)
{
for(int j=0;j<Object.dane->kolumna;j++)
{
Object.dane->wsk[i][j]=rand()%100+1;
}
}
return Object;
}
Matrix::Mref Matrix::operator()(int i, int j)
{
return Mref(*this,i,j);
}
Matrix::CountingReference::CountingReference()
{
wiersz=0;
kolumna=0;
wsk=NULL;
countingReference=0;
}
Matrix::CountingReference::CountingReference(int wier, int kol)
{
countingReference=0;
wiersz=wier;
kolumna=kol;
wsk=new double*[wier];
for(int i=0;i<wier;i++)
{
wsk[i]=new double[kol];
}
}
Matrix::CountingReference::~CountingReference()
{
for(int i=0;i<wiersz;i++)
{
delete [] wsk[i];
}
delete [] wsk;
wsk=NULL;
}
Matrix::CountingReference *Matrix::CountingReference::detach()
{
CountingReference *pointer;
if(countingReference==0)
{
return this;
}
pointer=new CountingReference(wiersz,kolumna);
for(int i=0;i<wiersz;i++)
{
for(int j=0;j<kolumna;j++)
{
pointer->wsk[i][j]=wsk[i][j];
}
}
countingReference--;
return pointer;
}
Matrix::Mref::operator double() const
{
return s.read(i,k);
}
Matrix::Mref &Matrix::Mref::operator = (double c)
{
s.write(i,k,c);
return *this;
}
Matrix::Mref &Matrix::Mref::operator = (const Mref& ref)
{
return operator= ((double)ref);
}
main.cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <fstream>
#include "Matrix.h"
using namespace std;
int main()
{
Matrix A(3,3);
Matrix B(3,3);
Matrix C(3,3);
Matrix D(3,3);
Matrix F();
Random(B);
Random(C);
Random(D);
cout<<"B: "<<endl<<B<<endl;
cout<<"C: "<<endl<<C<<endl;
cout<<"D: "<<endl<<D<<endl;
cout<<A.readref()<<endl;
A=B+C;
cout<<A.readref()<<endl;
A=B=C=D;
cout<<A.readref()<<endl;
return 0;
}
I know, that somewhere in my destructors I don't release memory. But I already checked everything and still didn't find the problem... I don't even know which of my pointers i should release. Could you help me?
EDIT
Here is my Matrix.h
#include <iostream>
#include <cassert>
using namespace std;
class Matrix{
private:
class CountingReference
{
friend class Matrix;
public:
double **wsk;
int wiersz;
int kolumna;
int countingReference;
CountingReference();
CountingReference(int, int);
~CountingReference();
CountingReference* detach();
};
CountingReference *dane;
public:
class Mref
{
friend class Matrix;
Matrix& s;
int i,k;
Mref (Matrix& m, int r, int c): s(m), i(r), k(c) {}
public:
operator double() const;
Mref& operator = (double c);
Mref& operator = (const Mref& ref);
};
friend ostream& operator<<(ostream& o,const Matrix&);
friend ostream& operator<<(const Matrix&, ostream& o);
Matrix();
Matrix(int, int);
Matrix(const Matrix&);
~Matrix();
Matrix& operator=(const Matrix&);
Matrix operator+(const Matrix&) throw(string);
Matrix operator-(const Matrix&) throw(string);
Matrix operator*(const Matrix&) throw(string);
Matrix operator+=(const Matrix&) throw(string);
Matrix& operator-=(const Matrix&) throw(string);
Matrix& operator*=(const Matrix&) throw(string);
bool operator == (const Matrix &);
Matrix& LoadFromFile(const char*);
friend Matrix& Random(Matrix&);
double read(int, int) const;
int readref();
void write(int, int, const double);
Mref operator()(int, int);
friend class CountingReference;
};