Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
Welcome to the Intel Community. If you get an answer you like, please mark it as an Accepted Solution to help others. Thank you!
26748 Discussions

Deallocate error on pointer obtained through C_F_POINTER

Olivier_H_
Beginner
392 Views

Hi, 

I am facing an issue with ifort 17.0 (the same code was working fine with ifort 12.1 and 16.0) on a simple code where I try to deallocate the fptr returned by C_F_POINTER from ISO_C_BINDING (I associate there the pointer to a C allocated array of char). The error on program compiled with ifort 17.0 is:
forrtl: severe (173): A pointer passed to DEALLOCATE points to an object that cannot be deallocated

Here is the snippet of code:

program testalloc
  use ISO_C_BINDING
  implicit none

  interface
     function c_alloc(buf) bind(C,name="alloc_in_c")
       use ISO_C_BINDING
       integer(C_INT) :: c_alloc
       type(C_PTR), intent(out) :: buf
     end function c_alloc
  end interface

  type(C_PTR) :: cptr
  character, dimension(:), pointer :: fptr
  character(128) :: s
  integer :: len, i 

  len = c_alloc(cptr)
  call C_F_POINTER(cptr, fptr, (/len/))

  s = ' '
  do i=1,len
     s(i:i) = fptr(i)
  end do

  print *,"obtained string = ",TRIM(s)
  
  if (associated(fptr)) then
     deallocate(fptr)
  end if

end program testalloc

 

As no error was detected with previous version of the compiler, I was wondering if it could be a bug in this 17.0 version or if my code was simply not valid but that was not detected/enforced previously?

Thanks
Olivier

0 Kudos
10 Replies
Steve_Lionel
Black Belt Retired Employee
392 Views

Patient: Doctor, it hurts when I do this!
Doctor: Then don't do that!

Your code is not legal. You must not DEALLOCATE a pointer that wasn't allocated through Fortran ALLOCATE. (This could be through a call to CFI_allocate when using a C descriptor in C, but you're not doing that.) Furthermore, the pointer you get with C_F_POINTER is generally not valid for use with DEALLOCATE, 

That the program appeared to work in an earlier compiler version is not an indication of a bug in the newer version.

Olivier_H_
Beginner
392 Views

Ah! Thanks Doctor for pointing this out :-)

So if I understand correctly, the only valid way to free this memory from Fortran is by calling a C function to do so on the C_PTR 'cptr' right?

Just to make sure: in case I want to do this in a bloc where I do not have a reference to the initial C_PTR anymore but only the associated Fortran pointer, will a call to C_LOC(fptr) give me the exact same C_PTR which I can then pass to a C free function?

Thanks
Olivier

jimdempseyatthecove
Black Belt
392 Views

Be careful. Someone (even you) may change the code later to have fptr point to a Fortran allocated object. The safest route may be to preserve the INTEGER(C_PTR) value and to insert debug code (in debug build) to assert the equivalence. And to null out both copies after deallocation.

Jim Dempsey

Steve_Lionel
Black Belt Retired Employee
392 Views

As Jim suggests, as long as you don't change the pointer assignment, C_LOC should work. You may want to look into the F2015 C interoperability features that Intel Fortran now supports. This adds the ability to share Fortran pointers and allocatables with C.

Olivier_H_
Beginner
392 Views

Thanks for the tips, I'll make sure to be careful when manipulating this fptr (due to complexity of the code and use-cases, it might involve adding a marker to specify whether the data comes from the C library or was directly allocated in Fortran). 

Concerning the new F2015 C interoperability features, sharing Fortran pointers and allocatables with C sounds great to have but will not help in my case, as my C library is common not only to Fortran code but also to other programming languages (Python, Java, C++ to name a few).

Olivier

 

jimdempseyatthecove
Black Belt
392 Views

Steve,

An esoterically question.

Assume the allocation is performed in C. Assume the object allocated is an array of reals. Assume, C_F_POINTER is used to properly construct an array descriptor for the pointer.

Now:    fptr = LargerArrayOfReals

Where realloc lhs is enabled?

IOW, does the array descriptor for pointer contain a flag that indicates if realloc_lhs is permitted or not permitted?

Jim Dempsey

Steve_Lionel
Black Belt Retired Employee
392 Views

This is a pointer, not allocatable. realloc_lhs does not apply.

jimdempseyatthecove
Black Belt
392 Views

>>This is a pointer, not allocatable. realloc_lhs does not apply

Good to know. i.e. in situations where you expressly do not want to permit reallocation, you can use a pointer as opposed to an allocatable.

Jim Dempsey

Steve_Lionel
Black Belt Retired Employee
392 Views

I would not recommend that. Instead, use:

A(:) = whatever

As I describe here, the (:) disables automatic reallocation, though of course it's now up to you to make sure that the shapes match, just as with pointers. If you make a mistake, it may not get detected by bounds checking.

Koziol__Ben
Beginner
392 Views

The limitation on deallocating an fptr that was allocated in Fortran has proved challenging for my use case (Fortran allocatable array wrapped by Python/ctypes/NumPy). I see from the discussion a mention of Fortran 2015 C interoperability for sharing allocatables. I could not track down the documentation for this capability. Could you please point me in the right direction? Thank you!

Reply