- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This is a pointer, not allocatable. realloc_lhs does not apply.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page