Can C++ delete the Fortran pointer array?

Can C++ delete the Fortran pointer array?

tangzhanghong98@yahoo.com's picture

Dear all,

I have a mixed Fortran/C++ project by MSVC2010 + IVF2011 on Windows 7 64 bit system. I need to delete and reallocate the pointer array defined in Fortran code. However, the code will crash when delete the pointer array in C++.

The code is as follows:

Fortran:

  type outputobj0
    integer::intarraysize=0
    integer::doublearraysize=0
    integer,pointer::intarray(:)=>null()
    real*8,pointer::doublearray(:)=>null()
  end type
  
  type(outputobj0)::out
  call F_call_C(c_loc(out))

C++:
typedef struct outputobj0
{
    int intarraysize;
    int doublearraysize;
    int *intarray;
    double *doublearray;
}outputobj;
void F_call_C(outputobj *out)
{
  ...
  if(out->intarray)delete [] out->intarray;
  if(out->doublearray)delete [] out->doublearray;
  out->intarray = new int [out->intarraysize];
  out->doublearray= new int [out->doublearray];
}

The code will crash at this line:

  if(out->intarray)delete [] out->intarray;

I want to know whether it is possible to delete the point array declared in Fortran and renew it? How to modify the code to let it work?

Thanks,

Zhanghong Tang

7 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.
Tim Prince's picture

You would need C pointers in order for a C function to operate in any remotely portable way. You could look up the descriptor format for a given Fortran compiler, but the associated programming clearly would be non-portable.

tangzhanghong98@yahoo.com's picture

Dear Dr. Timp,

Thank you very much for your kindly reply. I have C pointers defined:
typedef struct outputobj0
{
int intarraysize;
int doublearraysize;
int *intarray;
double *doublearray;
}outputobj;

The C++ project is built as a dynamic linked library.
Have I missed anything?

Could you please tell me where to find detailed document?

Thanks,
Zhanghong Tang

Annalee (Intel)'s picture

The section on Mixed Language Programming in our documentation contains information on Standard Fortran and C Interoperability options.

jimdempseyatthecove's picture

The safest way is to have the C++ program call a FORTRAN subroutine to delete the object.
*** In your above guess at the C++ struct you are incorrect in assuming that a fortran array pointer is the same as a C++ item pointer.
Fortran:

type outputobj0
integer::intarraysize=0
integer::doublearraysize=0
integer,pointer::intarray(:)=>null()
real*8,pointer::doublearray(:)=>null()
end type

In the above, intarray and doublearray do not contain the address of the first element of an array (as is the case with the C++ struct you produced), instead, these are array descriptors (or will point to array descriptors). The array descriptor will contain information about the array (dimensions, address 0, stride, and other information). Array descriptors are not portable. It would be better to make these two entries (or add two entries) of type C_PTR that you initialize with LOC(intarray(1)) or better LOC(intarray(LBOUND(intarray)), same with doublearray.

Jim Dempsey

www.quickthreadprogramming.com
jimdempseyatthecove's picture

Note, "address 0" referrs to the address of where Array(0) would be located, and not (necessarily) the address of the allocated memory block.
When an array is ALLOCATE(Array(n)), the first element of the array is 1, not 0, however the address of the hypothetical 0'th entry is stored in the array descriptor (allocated memory block -4 for integer(4)). Had the allocation been: ALLOCATE(Array(0:n-1)), then the first element is (0) and the address in the array descriptor is the address of the allocated memory.
Also, should the implimentation store the pointer to the descriptor in the type, then the allocation may involve allocating not only the memory for the array, but the memory for the array descriptor as well. As to if the "integer,pointer::intarray(:)" in the type is a descriptor or pointer to descriptor, well this is an implimentation issue... subject to change. Therefore, whichever domain (C++/FORTRAN) performs the allocation, this should be the domain for the delete/deallocate/free.
Jim Dempsey

www.quickthreadprogramming.com
tangzhanghong98@yahoo.com's picture

Dear Dr. Dempsey,

Thank you very much for your kindly reply. Finally I gave up so complex operations since it is not portable. I let the Fortran code allocate/deallocate these arrays and C++ code only fills the values.

Thanks,
Zhanghong Tang

Login to leave a comment.