From help-octave-request at bevo dot che dot wisc dot edu Wed Dec 18 14:37:02 2002 Subject: A bit puzzled... From: "John W. Eaton" To: "Albert F. Niessner" Cc: Paul Kienzle , Octave Help Date: Wed, 18 Dec 2002 14:36:43 -0600 On 18-Dec-2002, Albert F. Niessner wrote: | However, in the other | (http://www.octave.org/mailing-lists/help-octave/2002/1163) you wrote: | "If the operation is not in place, or if you need a working vector, | allocate it beforehand: | | octave_value_list retval; | const Matrix A(args(0).matrix_value()); | const Matrix B(args(1).matrix_value()); | Matrix C(A.rows(),B.columns()); | F77_FUNC(f,F)(A.data(),B.data(),C.fortran_vec()); | retval(0) = C; | return retval;" | | But, if the data is being copied at the C.fortran_vec() routine, then | retval(0) = C cannot possibly contain the answer. Yes, it can. I believe the code above is correct. This sort of thing is used all the time in the Octave sources. | In fact, this is | exactly what I am seeing. If I make changes to allow for a copy | operation taking place I get a segmentation fault. I think it is from | retval(0) = fvec where 'double *fvec = C.fortran_vec();'. You don't want to do that. There shouldn't be a valid constructor for that sort of operation (I'm surprised that it even compiles). | I then walked through some of the octave code and I saw in Array.h that | the template defines fortran_vec() as 'return data()' which is defined | as 'return rep->data' which I think is T *data. So, I am not sure why | your example does not work or why you suggest a copy operation takes | place. There are two different fortran_vec member functions. The one you apparently saw is the when a const pointer is requested. In that case, no copy is needed because the const qualifier is a promise that you won't be modifying the data. The other version of fortran_vec is for non-const cases. It looks like this (Array.cc): template T * Array::fortran_vec (void) { if (rep->count > 1) { --rep->count; rep = new typename Array::ArrayRep (*rep); } return rep->data; } so this is where the copy happens. Since the Array object still points to valid memory (even though it may be a copy of the original data) it is perfecly valid to do something like: octave_value_list retval; ... Matrix M (some, size); // f77_function is going to fill M's data array with some values: F77_FUNC (f77_function, F77_FUNCTION) (M.fortran_vec ()); // M is still a handle for the data, so we can use it to construct // an octave_value object. retval(0) = M; return retval; jwe ------------------------------------------------------------- Octave is freely available under the terms of the GNU GPL. Octave's home on the web: http://www.octave.org How to fund new projects: http://www.octave.org/funding.html Subscription information: http://www.octave.org/archive.html -------------------------------------------------------------