-
Sparse matrix
hello. Everybody Im new in programming. Still learning. Currently I have a problem when designing a Sparse Matrix class. Class is based on a linked list which records only the non-zero elements. Source file seems to compile fine, but at a run it crashes. Debug reveals a segmentation fault, which is as far as I know connected with inproper memory allocation. However I don't seem to find the problem. This is just a base class which allows to insert non-zero elements and display them. I am using bloodshed Dev C++. Any help would be appreciated. thanks Milenkom.
Code:
#include <iostream>
using namespace std;
class Sparse
{
private:
class Elem
{
private:
int row,column;
double*elem;
Elem*next;
public:
Elem(){next=NULL;}
Elem(int a,int b,double h);
~Elem(){delete elem;}
Elem*& Next(){return next;}
double& Value()const{return *elem;}
int& Row(){return row;}
int& Column(){return column;}
};
Elem*first;
int rows;
int columns;
public:
Sparse(int,int);
~Sparse();
void Insert(int a,int b,double h);
friend ostream& operator<<(ostream&,Sparse&);
};
Sparse::Elem::Elem(int a,int b,double h)
{
elem=new double;
*elem=h;
next=NULL;
row=a;
column=b;
}
Sparse::Sparse(int a,int b):rows(a),columns(b)
{
}
Sparse::~Sparse()
{
Sparse::Elem*handy=first;
Sparse::Elem*prev;
while(handy!=NULL)
{
prev=handy;
handy=handy->Next();
delete prev;
}
}
void Sparse::Insert(int a,int b,double h)
{
Sparse::Elem*prvi=new Sparse::Elem(a,b,h);
Sparse::Elem*handy;
if(first==NULL)
{
first=prvi;
}
else
{
handy=first;
while(handy->Next()!=NULL)
{
handy=handy->Next();
}
handy->Next()=prvi;
}
}
ostream& operator<<(ostream &os,Sparse &s)
{
for(int j=1;j<=s.columns;j++)
{
for(int i=1;i<=s.rows;i++)
if(s.first->Column()==j && s.first->Row()==i)
{
cout<<s.first->Value()<<" ";
s.first=s.first->Next();
}
else
cout<<0<<" ";
cout<<"\n";
}
return os;
}
int main()
{
Sparse s1(10,10);
s1.Insert(1,1,10);
s1.Insert(2,1,20);
s1.Insert(3,2,30);
cout<<s1;
system("PAUSE");
return 0;
}
-
It looks like the constructor of Sparse leaves Elem* first uninitialized (it won't be 0).
There are other strangeness, such as allocating the double dynamically in Elem. Any reason why you don't use the standard containers for the underlying low level stuff?
-
You could be more consistent with your use of constructor initialiser lists and use them in Elem's constructor too. Initialise all variables that you can this way.
-
Don't worry I already fixed the problem. I also overloaded (int,int) operator which really simplifies the code for ostream<< operator on few lines.
I could use member initializer list, but its not really necessary. Currently i am still learning, although almost at end. The book i used Primer C++ is very thourough, but the examples are too simple Im afraid. Thats why Im trying to solve more demanding examples (this one is from Sharam Hekmat).
-
Incidentally,
Code:
ostream& operator<<(ostream &os,Sparse &s)
should be:
Code:
ostream& operator<<(ostream &os, const Sparse &s)