problem with constructor/destructor?

T

tonysuper

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_=b.v_; }
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_;
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_=b.v_;}
~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_; 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*vec2;
}

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/=denom;
}
}
 
A

Allan Bruce

tonysuper said:
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?

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
 
P

Peter van Merkerk

tonysuper said:
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.

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.
 
T

tonysuper

Peter van Merkerk ha scritto:
tonysuper said:
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.


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.

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

John Harrison

tonysuper said:
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_=b.v_; }
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_;
return res;}
};


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

john
 
T

tonysuper

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_=b.v_; }
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_=b.v_;
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_;
return res;}
};
 
J

John Harrison

tonysuper said:
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_=b.v_; }
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_=b.v_;
return *this;
}


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.
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_;
return res;}
};


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

john
 
T

tonysuper

This will fail on self assignment

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

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

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

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

John Harrison

tonysuper said:
if (this= &b) return *this;
at the first line is sufficient?
Yes.


what do you mean?

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
can you make me an example of inefficiency with my code?

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
 
T

tonysuper

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.

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top