Connecting Tech Pros Worldwide Forums | Help | Site Map

problem with constructor/destructor?

tonysuper
Guest
 
Posts: n/a
#1: Jul 22 '05
Probably i have problem with co/des :

if i call functions wich returns farray, programs go seg fault.

if i comment destructor.. programs work but do not free memory.

Any suggestion?

farray and fmatrix are fast 1-index based array and matrix. f means fortran.

my aim is to write a very simple class faster than TNT (template
numerical toolkit)

// -*-C++-*-
#include <cmath>
using std::sqrt;
namespace tonymatrix
{
template <class T>
class farray
{
T* v_;
int dim_;
public:
explicit inline farray(): dim_(0), v_(0) {};
explicit inline farray (int a): dim_(a) {v_= new T[dim_];}
// inline ~farray() {delete []v_;};
inline farray (const farray &b):dim_(b.size()) { v_= new T[dim_];
for (int i=0;i!=dim_;i++) v_[i]=b.v_[i]; }
inline T& operator() (int i){return v_[i-1];}
inline const T& operator() (int i) const {return v_[i-1];}
inline T& operator[] (int i){return v_[i-1];}
inline const T& operator[] (int i) const {return v_[i-1];}
inline int dim() const {return dim_;}
inline int dim1() const {return dim_;}
inline int size() const{return dim_;}
inline T sum() const {T res; for (int i=0;i!=dim_;i++) res+=v_[i];
return res;}
};
template <class T>
class fmatrix {
T* v_;
int dim1_,dim2_;
public:
explicit fmatrix (int a,int b): dim1_(a), dim2_(b) {v_= new T[a*b]; }
explicit inline fmatrix (const fmatrix &b):
dim1_(b.dim_1),dim2_(b.dim2_) {int dim=dim1_*dim2_;v_= new T[dim]; for
(int i=0;i!=dim;i++) v_[i]=b.v_[i];}
~fmatrix() {delete []v_;}
inline T& operator() (int i, int j){return v_[(i-1)*dim1_+j-1];}
inline const T& operator() (int i, int j) const {return
v_[(i-1)*dim1_+j-1];}
inline int dim1() const {return dim1_;}
inline int dim2() const {return dim2_;}
inline int size() const {return dim1_*dim2_;}
inline T sum() const {T res; int dim=dim1_*dim2_; for (int
i=0;i!=dim;i++) res+=v_[i]; return res;}
};
template <class T> inline T dot_product(const farray<T> &vec1, const
farray<T> &vec2)
{
T res=0;
int a=vec1.size(), b=vec2.size();
if (a>b) a=b;
for (int i=1;i<=a;i++)
{
res+=vec1[i]*vec2[i];
}

return res;
}
template <class T> inline double norm(const farray<T> &vec1)
{
return sqrt((dot_product(vec1,vec1)));
}
template <class T> inline void normalize (farray<T> &vec)
{
int a=vec.size();
double denom= norm(vec);
if (denom!=0) for (int i=1;i<=a;i++) vec[i]/=denom;
}
}

--
Hai recensioni nel cassetto di musica, cinema, letteratura,fumetti??
Ascolta e pentiti e se hai tempo vergognati
http://tonysuper.altervista.org

Allan Bruce
Guest
 
Posts: n/a
#2: Jul 22 '05

re: problem with constructor/destructor?



"tonysuper" <mionick@altervista.org> wrote in message
news:2m4auhFifn94U1@uni-berlin.de...[color=blue]
> Probably i have problem with co/des :
>
> if i call functions wich returns farray, programs go seg fault.
>
> if i comment destructor.. programs work but do not free memory.
>
> Any suggestion?
>[/color]

without looking at your code, you should think to yourself at this point:

My program is crashing when trying to free memory, therefore I have either:
1) already freed the memory
2) have written/accessed my memory past the allocated bounds.

Unless you have other code in your d'tor which is causing the problems.
Allan


Peter van Merkerk
Guest
 
Posts: n/a
#3: Jul 22 '05

re: problem with constructor/destructor?


tonysuper wrote:
[color=blue]
> Probably i have problem with co/des :
>
> if i call functions wich returns farray, programs go seg fault.
>
> if i comment destructor.. programs work but do not free memory.
>
> Any suggestion?
>
> farray and fmatrix are fast 1-index based array and matrix. f means
> fortran.[/color]

Possibly this may indirectly be the cause of the problem. There is no
index checking in your code. So if someone accidentally calls uses a 0
index, the memory that the destructor needs for proper cleanup might get
corrupted. This may go undetected as long as the destructor isn't
called. What you could do is place assert(i>0) at strategic places (such
as operator[]) to detect when someone uses an invalid index.

--
Peter van Merkerk
peter.van.merkerk(at)dse.nl
tonysuper
Guest
 
Posts: n/a
#4: Jul 22 '05

re: problem with constructor/destructor?


Peter van Merkerk ha scritto:[color=blue]
> tonysuper wrote:
>[color=green]
>> Probably i have problem with co/des :
>>
>> if i call functions wich returns farray, programs go seg fault.
>>
>> if i comment destructor.. programs work but do not free memory.
>>
>> Any suggestion?
>>
>> farray and fmatrix are fast 1-index based array and matrix. f means
>> fortran.[/color]
>
>
> Possibly this may indirectly be the cause of the problem. There is no
> index checking in your code. So if someone accidentally calls uses a 0
> index, the memory that the destructor needs for proper cleanup might get
> corrupted. This may go undetected as long as the destructor isn't
> called. What you could do is place assert(i>0) at strategic places (such
> as operator[]) to detect when someone uses an invalid index.
>[/color]

even with bound checking the problem remains... it is not a problem of bound

--
Hai recensioni nel cassetto di musica, cinema, letteratura,fumetti??
Ascolta e pentiti e se hai tempo vergognati
http://tonysuper.altervista.org
John Harrison
Guest
 
Posts: n/a
#5: Jul 22 '05

re: problem with constructor/destructor?



"tonysuper" <mionick@altervista.org> wrote in message
news:2m4auhFifn94U1@uni-berlin.de...[color=blue]
> Probably i have problem with co/des :
>
> if i call functions wich returns farray, programs go seg fault.
>
> if i comment destructor.. programs work but do not free memory.
>
> Any suggestion?
>
> farray and fmatrix are fast 1-index based array and matrix. f means[/color]
fortran.[color=blue]
>
> my aim is to write a very simple class faster than TNT (template
> numerical toolkit)
>
> // -*-C++-*-
> #include <cmath>
> using std::sqrt;
> namespace tonymatrix
> {
> template <class T>
> class farray
> {
> T* v_;
> int dim_;
> public:
> explicit inline farray(): dim_(0), v_(0) {};
> explicit inline farray (int a): dim_(a) {v_= new T[dim_];}
> // inline ~farray() {delete []v_;};
> inline farray (const farray &b):dim_(b.size()) { v_= new T[dim_];
> for (int i=0;i!=dim_;i++) v_[i]=b.v_[i]; }
> inline T& operator() (int i){return v_[i-1];}
> inline const T& operator() (int i) const {return v_[i-1];}
> inline T& operator[] (int i){return v_[i-1];}
> inline const T& operator[] (int i) const {return v_[i-1];}
> inline int dim() const {return dim_;}
> inline int dim1() const {return dim_;}
> inline int size() const{return dim_;}
> inline T sum() const {T res; for (int i=0;i!=dim_;i++) res+=v_[i];
> return res;}
> };[/color]

You have not defined an assignment operator for your class, therefore you
are freeing the same memory twice.

john


tonysuper
Guest
 
Posts: n/a
#6: Jul 22 '05

re: problem with constructor/destructor?


ok

it was the operator= missing
now it works
any suggestion for efficiency in this class?

template <class T>
class farray
{
T* v_;
int dim_;
public:
explicit inline farray(): dim_(0), v_(0) {};
explicit inline farray (int a): dim_(a) {v_= new T[dim_];}
inline ~farray() {delete [] v_; v_= 0; };
inline farray (const farray &b):dim_(b.size()) { v_= new T[dim_];
for (int i=0;i!=dim_;i++) v_[i]=b.v_[i]; }
inline farray operator=(const farray&b)
{
if (v_!=0) {
delete [] v_;
v_=0;
}
dim_=b.dim_;
v_=new T[dim_];
for (int i=0;i!=dim_;i++) v_[i]=b.v_[i];
return *this;
}

inline T& operator() (int i){assert(i<=dim_&&i>0); return v_[i-1];}
inline const T& operator() (int i) const
{assert(i<=dim_&&i>0);return v_[i-1];}
inline T& operator[] (int i){assert(i<=dim_&&i>0);return v_[i-1];}
inline const T& operator[] (int i) const
{assert(i<=dim_&&i>0);return v_[i-1];}
inline int dim() const {return dim_;}
inline int dim1() const {return dim_;}
inline int size() const{return dim_;}
inline T sum() const {T res; for (int i=0;i!=dim_;i++) res+=v_[i];
return res;}
};




--
Hai recensioni nel cassetto di musica, cinema, letteratura,fumetti??
Ascolta e pentiti e se hai tempo vergognati
http://tonysuper.altervista.org
John Harrison
Guest
 
Posts: n/a
#7: Jul 22 '05

re: problem with constructor/destructor?



"tonysuper" <mionick@altervista.org> wrote in message
news:2m4hhlFh668jU3@uni-berlin.de...[color=blue]
> ok
>
> it was the operator= missing
> now it works
> any suggestion for efficiency in this class?
>
> template <class T>
> class farray
> {
> T* v_;
> int dim_;
> public:
> explicit inline farray(): dim_(0), v_(0) {};
> explicit inline farray (int a): dim_(a) {v_= new T[dim_];}
> inline ~farray() {delete [] v_; v_= 0; };
> inline farray (const farray &b):dim_(b.size()) { v_= new T[dim_];
> for (int i=0;i!=dim_;i++) v_[i]=b.v_[i]; }
> inline farray operator=(const farray&b)
> {
> if (v_!=0) {
> delete [] v_;
> v_=0;
> }
> dim_=b.dim_;
> v_=new T[dim_];
> for (int i=0;i!=dim_;i++) v_[i]=b.v_[i];
> return *this;
> }[/color]

This will fail on self assignment

farray x(10);
x = x; // this crashes

Of course you would never code that but its quite easy to code something
that does result in self assignment so you should protect yourself against
it.
[color=blue]
>
> inline T& operator() (int i){assert(i<=dim_&&i>0); return v_[i-1];}
> inline const T& operator() (int i) const
> {assert(i<=dim_&&i>0);return v_[i-1];}
> inline T& operator[] (int i){assert(i<=dim_&&i>0);return v_[i-1];}
> inline const T& operator[] (int i) const
> {assert(i<=dim_&&i>0);return v_[i-1];}
> inline int dim() const {return dim_;}
> inline int dim1() const {return dim_;}
> inline int size() const{return dim_;}
> inline T sum() const {T res; for (int i=0;i!=dim_;i++) res+=v_[i];
> return res;}
> };
>[/color]

Use reference counting with copy-on-write. You should avoid copying as much
as possible.

john


tonysuper
Guest
 
Posts: n/a
#8: Jul 22 '05

re: problem with constructor/destructor?


[color=blue]
> This will fail on self assignment
>
> farray x(10);
> x = x; // this crashes[/color]

if (this= &b) return *this;
at the first line is sufficient?

[color=blue]
> Use reference counting with copy-on-write. You should avoid copying as much
> as possible.[/color]

what do you mean?
can you make me an example of inefficiency with my code?

--
Hai recensioni nel cassetto di musica, cinema, letteratura,fumetti??
Ascolta e pentiti e se hai tempo vergognati
http://tonysuper.altervista.org
John Harrison
Guest
 
Posts: n/a
#9: Jul 22 '05

re: problem with constructor/destructor?



"tonysuper" <mionick@altervista.org> wrote in message
news:2m4i6lFim580U1@uni-berlin.de...[color=blue]
>[color=green]
> > This will fail on self assignment
> >
> > farray x(10);
> > x = x; // this crashes[/color]
>
> if (this= &b) return *this;
> at the first line is sufficient?[/color]

Yes.
[color=blue]
>
>[color=green]
> > Use reference counting with copy-on-write. You should avoid copying as[/color][/color]
much[color=blue][color=green]
> > as possible.[/color]
>
> what do you mean?[/color]

For a quick introduction to reference counting and copy on write try these
articles http://www.gotw.ca/gotw/043.htm, http://www.gotw.ca/gotw/044.htm,
http://www.gotw.ca/gotw/045.htm
[color=blue]
> can you make me an example of inefficiency with my code?
>[/color]

farray some_calculation()
{
farray res;
...
return res;
}

farray a = some_calculation();

It's likely that when some_calculation returns the entire farray will be
copied. With reference counting you can be sure that it will not be.

john


tonysuper
Guest
 
Posts: n/a
#10: Jul 22 '05

re: problem with constructor/destructor?


[color=blue]
> It's likely that when some_calculation returns the entire farray will be
> copied. With reference counting you can be sure that it will not be.[/color]

yeah i understand...
but if i'd need this stuff probably i'll better use directly the very
good TNT by Pozo and adapt to my need adding some stuff.



In fact my idea was just to write a faster and simpler version of Tnt...
it is simpler in the mean that the assembly code of my program does not
contain any call like the code generated by the fortran litteral
translation.

TNT which is ref counted instead generates a function to access array
elements .

Strangely performance difference between my class and TNT are less than
0.5 % (probably cause RAM is slower than cache-function call) and both
with gnu g++ are 40 % FASTER than F90 compiled with Intel ifort 8.0

both g++ and ifort are used with a lot of flags to assure best
optimization.

--
Hai recensioni nel cassetto di musica, cinema, letteratura,fumetti??
Ascolta e pentiti e se hai tempo vergognati
http://tonysuper.altervista.org
Closed Thread