[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 18-Dec-2002, Albert F. Niessner <address@hidden> 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 <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
-------------------------------------------------------------