home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / comp / lang / cplus / 18155 < prev    next >
Encoding:
Text File  |  1992-12-18  |  2.6 KB  |  85 lines

  1. Newsgroups: comp.lang.c++
  2. Path: sparky!uunet!usc!zaphod.mps.ohio-state.edu!caen!uvaarpa!murdoch!virginia.edu!gs4t
  3. From: gs4t@virginia.edu (Gnanasekaran Swaminathan)
  4. Subject: Re: Matrix Addition  Was Re: Complex Addition.
  5. Message-ID: <1992Dec17.204049.20009@murdoch.acc.Virginia.EDU>
  6. Keywords: operator, memory leak
  7. Sender: usenet@murdoch.acc.Virginia.EDU
  8. Organization: University of Virginia
  9. References: <1992Dec11.170849.18525@rs6000.bham.ac.uk> <1992Dec11.232954.7071@borland.com> <36223@sophia.inria.fr>
  10. Date: Thu, 17 Dec 1992 20:40:49 GMT
  11. Lines: 72
  12.  
  13. gchow@hawai.inria.fr (Gloria Chow) writes:
  14. : MATRIX& MATRIX::operator+( const MATRIX& addend )
  15. : {
  16. : register int    i,j;
  17. : MATRIX          sum(nrows, ncols);
  18. :     for( i=0 ; i<nrows ; i++ )
  19. :         for ( j=0 ; j<ncols ; j++ )
  20. :             sum.entry[i][j] = entry[i][j] + addend.entry[i][j];
  21. :     return sum;
  22. : }
  23. : Okay, the problem is when I tried to use the "+" operator as follows:
  24. :     matrix_c = matrix_a + matrix_b;
  25. : the "+" operation works and sum contains the proper matrix, that is until
  26. : "+" finishes and goes out of scope.  The "return" statement makes a temporary
  27. : copy of sum (ie. the values of its nrows, ncols, and the pointer entry), and
  28. : then proceed to destroy sum automatically.  So, now the entry pointer of this
  29. : temporary is no longer pointing to a valid block of memory!!   
  30.  
  31. You are returning a reference to a local variable sum.
  32. That is, no temporary copy is made in your case.
  33. So, when the function operator+ goes out of scope, sum
  34. gets destroyed and hence, the reference refers to junk.
  35.  
  36. One technique advocated several times in this forum and
  37. by several good books is to use reference counting and 
  38. return by value in case of big objects like Matrix.
  39.  
  40. For example,
  41.  
  42. class Matrix {
  43.     struct MatRep {
  44.         int    ref;
  45.         int      rows, cols;
  46.         double*    d;
  47.     
  48.         MatRep (int r, int c)
  49.         : ref(1), rows(r), cols(c), d(new double[rows*cols]) {}
  50.         ~MatRep () { delete [] d; }
  51.     }* rep;
  52. public:
  53.     Matrix (int r, int c): rep(new MatRep(r,c)) {}
  54.     Matrix (const Matrix& m): rep (m.rep) { ++rep->ref; }
  55.     ~Matrix () { if (--rep->ref == 0) delete rep; }
  56.  
  57.     double    operator () (int i, int j) { return rep->d[i*rep->rows+j]; }
  58.     Matrix& operator =  (const Matrix& m) {
  59.         if (this != &m) {
  60.             this->Matrix::~Matrix (); // self destruct
  61.             rep = m.rep; ++rep->ref;
  62.         }
  63.         return *this;
  64.     }
  65.  
  66.     friend Matrix  operator + (const Matrix& a, const Matrix& b);
  67. };
  68.  
  69. // note the return by value here
  70. Matrix operator + (const Matrix& a, const Matrix& b)
  71. {
  72.     Matrix sum (a.rep->rows, a.rep->cols);
  73.     for (int i=0; i < sum.rep->rows * sum.rep->cols;  i++)
  74.         sum.rep->d[i] = a.rep->d[i] + b.rep->d[i];
  75.     return sum;
  76. }
  77.     
  78.     
  79.