Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!bywater!arnor!watson!blinn.watson.ibm.com!mittle From: mittle@blinn.watson.ibm.com (Josh Mittleman) Newsgroups: comp.lang.c++ Subject: Re: Beginners problems (longish) Message-ID: <1991Mar14.164053.19356@watson.ibm.com> Date: 14 Mar 91 16:40:53 GMT References: <1991Mar13.170912.4020@cs.UAlberta.CA> Sender: @watson.ibm.com Reply-To: mittle@ibm.com Organization: IBM T. J. Watson Research Lines: 64 The problem is that you haven't implemented the copy constructor, matrix::matrix(const matrix&) When your multiplication routine return out, what is returned is a field-by-field copy of out. It copies the value of each field; in particular, it copies the value of the pointer out.m. So, we have a new matrix which points to the same double array of floats as out. When you exit matrix::operator*, out goes out of scope, and the destructor runs, deleting the data now used by out and the return matrix. Your lucky, by the way. This kind of error can be a royal pain to discover. You can solve your problem by adding matrix::matrix(const matrix&): matrix::matrix(const matrix& M) { rows = M.rows; cols = M.cols; m = new float*[rows]; for (i = 0; i < rows; i++) { m[i] = new float[cols]; for (int j = 0; j < cols; j++) { m[i][j] = M[i][j]; } } } You should also implement matrix::operator=(const matrix&), which will copy the target matrix element by element, and will all deal with dimension mismatch in some way. Otherwise, a statement like: matrix m(2,2), n(2,2); ... m = n; will copy field-by-field, not element-by-element. You also asked: ostream& operator<<(ostream& s, matrix& m) // m must be a reference, why ? It doesn't have to be a reference, but it prevents an unnecessary copy operation. If you pass an object by value, then the function has to make a temporary copy of the object. With large objects, that wastes time. Actually, I recommend changing it to: ostream& operator<<(ostream& s, const matrix& m) ^^^^^ This prevent you from accidently changing m within the function. Whenever your function shouldn't change the value of its argument, make the argument a const &. Whenever the function shouldn't change the value of the calling object (*this), make the function const, if your version of C++ supports that. =========================================================================== Josh Mittleman (mittle@ibm.com or joshua@paul.rutgers.edu) J2-C28 T.J. Watson Research Center, PO Box 704, Yorktown Heights, NY 10598