- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Is there a way to move the data from a pointer to an allocatable without doing a copy ?
The data is allocated in C, but used and deallocated in fortran in a dimension(:),pointer, but then it needs to be attached to a class, but i dont see a way of moving the data to the allocatable without a copy.
Thanks.
Pat.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, you can't do this. And I hope you aren't using Fortran DEALLOCATE to deallocate storage allocated in C. You can convert a C pointer to a Fortran pointer (which you aren't allowed to deallocate), but ALLOCATABLEs are in their own realm. Polymorphism is another barrier here - even with the new C descriptor support in 16.0, you can't make polymorphic objects interoperable with C.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Just to have clear idea on what i am talking about here is a sample code below. I understand for a structure it is complicated but for a basic type , as long as i keep track of all my allocation and I am sure this pointer is not referenced anywhere else i should be ok ?
#include <stdlib.h> #include <stdio.h> int* alloc(int n) { int i; int *p=malloc(sizeof(int)*n); printf("allocate int array size %d\n",n); for (i=0;i<n;i++){ p=i; printf("p %d = %d\n",i,p); } return p; }
and
program foo use iso_c_binding type(c_ptr) :: c_array integer ,dimension(:),pointer ::fc_array integer ,dimension(:),allocatable :: array integer :: n interface type(c_ptr) function alloc(n) bind(c) use iso_c_binding integer(c_int),value :: n end function end interface n=20 c_array=alloc(n) call c_f_pointer(c_array,fc_array,(/n/)) print *,fc_array !move fc_array storage to fc_array ?? allocate(array(n)) array=fc_array deallocate(array) ! Forbidden ???? but working ? deallocate(fc_array) end program foo
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That last deallocate is indeed forbidden. That it seems to "work" is an accident, and it could corrupt memory. Don't do it. But you can now (in 16.0) do this:
#include "ISO_Fortran_binding.h" #include <stdio.h> #include <stdlib.h> extern "C" int alloc(CFI_cdesc_t * dv, int n) { CFI_index_t lower[1], upper[1]; int i, ret; int* p; lower[0] = 1; upper[0] = n; ret = CFI_allocate(dv, lower, upper, 0); if (ret == CFI_SUCCESS) { printf("allocate int array size %d\n", n); p = (int *) dv->base_addr; for (i = 0; i < n; i++){ p = i; printf("p %d = %d\n", i, p); } } return ret; }
program foo use iso_c_binding integer(c_int) ,dimension(:),allocatable :: array integer(c_int) :: n, ret interface integer(c_int) function alloc(array,n) bind(c) import integer(c_int), dimension(:), allocatable :: array integer(c_int), value :: n end function end interface n=20 ret = alloc(array,n) print *,array deallocate(array) end program foo
Still can't make in polymorphic, though.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am not worry about polymorphic at all, and since the library design in C does not depend on me, all i have is a C wrapper and i could use it to assign the base_addr ,CFI_ssetpointer ?
I will do some more test and get familiar with the new CFI functions.
Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The way you'd have to do this with CFI_setpointer is to create a separate C descriptor with CFI_establish, that points to malloced storage, and then use CFI_setpointer to do the pointer assign. It would then be not allowed to deallocate it in Fortran nor could you make this an allocatable.
You aren't allowed to modify the base_addr component yourself.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page