From: andy@federation.gatech.edu (Andy Register)
Newsgroups: comp.lang.c++
Subject: Re: Matrix Addition  Was Re: Complex Addition.
Keywords: operator, memory leak
Date: 17 Dec 92 20:03:53 GMT
Organization: CERL-EE, Georgia Institue of Technology

In article <36223@sophia.inria.fr> gchow@hawai.inria.fr (Gloria Chow) writes:
 >In article <1992Dec11.232954.7071@borland.com>, pete@borland.com (Pete Becker) writes:
 >|> In article <1992Dec11.170849.18525@rs6000.bham.ac.uk> pickerig@eee.bham.ac.uk (Guy Pickering) writes:
 >|> >In ARM, the code for the `+` operator for the complex class is given as:
 >
 >class MATRIX
 >{
 >protected:
 >    double      **entry;
 >    int         nrows, ncols;
 >public:
 >
 >the "+" operation works and sum contains the proper matrix, that is until
 >"+" finishes and goes out of scope.  The "return" statement makes a temporary
 >copy of sum (ie. the values of its nrows, ncols, and the pointer entry), and
 >then proceed to destroy sum automatically.  So, now the entry pointer of this
 >temporary is no longer pointing to a valid block of memory!!   
 >
 >Is this really what happened?  I am new to C++, I am not sure my interpretation
 >is correct.  But all I can tell is that this simple addition and assignment 
 >sequence DOESN'T work, and I don't know how to get around it.  HELP!!
 >
 >gloria

In general when you have a pointer in your class data you have to be
especially careful or the situation you describe will occur.  Also, if your
constructor calls new() then the following is probably appropriate advice.

There are two ways to correct the problem you are experiencing:  make the
class a concrete data type or use reference counting.

To make the class concrete you have to either, be *positive* that the
compiler supplied copy constructor and operator= functions are appropriate
for the data in your class or you have to supply these functions so that
the proper behavior results.  Almost always, certainly this case,
when your data includes a pointer you have to explicitly write a copy
constructor and an operator= method.  The copy constructor acts just
like the default constructor (i.e. allocates new storage) except that
it also performs a deep copy of the data items being pointed to.  The
operator= method should also performs a deep copy.  Note that a shallow
copy, only the pointer and not the underlying data copied, is the default.
All this extra stuff gets delete'ed when the temp goes out of scope and the
destructor is called.

To use reference counting, you also have to supply your own copy ctor
and operator=.  In this case, a true copy is not made, only a reference
to some original memory location.  When you say x=y, a shallow copy is
made, that is the pointer in x points to the same location as the pointer
in y but a reference count in y is incremented.  Same with copy ctor.
When the variable goes out of scope, the dtor is called. The reference
count is decremented and if the reference count is zero, the memory
is delete'ed.  There are some twists in the class data since all
objects that reference the same memory location must have access to 
this shared reference count but that is pretty easy ot accomplish.

My advice is to make the class concrete by providing deep copy
in the copy ctor and operator=.  This is the easiest to understand.  Later
when you have experience on your side (and a couple of good reference
books!) you can have a go at the reference counting idiom.  Coplien
and Eckel both cover this topic.

I hope I got that right, but if I did not, we will know soon!  (grin)

Toodles
Andy
Newsgroups: comp.lang.c++