I have a question related to one asked some years ago on Intel Developer Forum about the in-place reshaping of an array.
In short, the answer was that an array of a certain rank can be allocated, and a pointer created that refers to the same memory location (i.e. in-place), but with a different rank, e.g.:
use, intrinsic :: ISO_C_BINDING
integer, allocatable, target :: rank1_array(:)
integer, pointer :: rank3_array(:,:,:)
integer :: i
! Allocate rank1_array
allocate(rank1_array(24))
! Created rank3_pointer to rank1_array
call C_F_POINTER (C_LOC(rank1_array), rank3_array, [3,2,4])
! Now rank3_array is the same data as rank1_array, but a 3-dimension array with bounds (3,2,4)
My question is now that if I deallocate
the original array rank1_array
, why is it that the pointer rank3_array
is still associated, and can be used without a problem (seemingly). Thus, if I append the code segment from above with:
! initialise the allocated array
rank1_array = [(i, i=1,24)]
! then deallocate it
deallocate(rank1_array)
! now do stuff with the pointer
print *, associated(rank3_array)
rank3_array(2,2,1) = 99
print *, rank3_array
Compiling and running this program gives me the output
gfortran -Wall my_reshape.f90 -o my_reshape
./my_reshape
T
1 2 3 4 99 6 7 ... 23 24
If the memory of rank1_array
was deallocated, why does rank3_array
still function unless it is a copy of the original? Was the initial reshape then in-place or not? Would be very grateful if someone could explain this behaviour to me.
I'm using gfortran 6.1.0 of that is of interest.
Edit/Update:
As the accepted answer by @francescalus indicates, the real issue here is how I (incorrectly!) handled pointers in general and not the in-place reshape with C_F_POINTER
in particular. The strange behaviour I saw was just a result of undefined behaviour due to non-compliant fortran code I wrote. Based on @francescalus answer and comments, I did more reading online and thought it might be useful to give a link to a relevant section of a Fortran Reference Manual that very clearly explains how pointers and allocatable arrays should be handled.