help-octave
[Top][All Lists]
Advanced

[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
-------------------------------------------------------------



reply via email to

[Prev in Thread] Current Thread [Next in Thread]