[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
A bit puzzled...
From: 
John W. Eaton 
Subject: 
A bit puzzled... 
Date: 
Wed, 18 Dec 2002 14:36:43 0600 
On 18Dec2002, Albert F. Niessner <address@hidden> wrote:
 However, in the other
 (http://www.octave.org/mailinglists/helpoctave/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 nonconst cases. It looks like this (Array.cc):
template <class T>
T *
Array<T>::fortran_vec (void)
{
if (rep>count > 1)
{
rep>count;
rep = new typename Array<T>::ArrayRep (*rep);
}
return rep>data;
}
so this is where the copy happens. Since the Array<T> 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
