In the following code, I am trying to increase the length of a(:) by first allocating a temporary array buf(:) of larger size, copying the contents of a(:) to buf(:), and then using move_alloc() to copy the array descriptor from buf to a:
program main
implicit none
integer, allocatable :: a(:), buf(:)
allocate( a(2) )
a = [1,2]
allocate( buf( 4 ), source= 0 ) !! (1)
buf( 1:2 ) = a( 1:2 ) !! (2)
! allocate( buf( 4 ), source= a ) !! (3)
! deallocate( a ) !! (4)
call move_alloc( buf, a )
print *, "a(:) = ", a(:)
end
Here, I have two questions: First, in line 4, is it necessary to deallocate a(:) explicitly before calling move_alloc()...? Both gfortran and Intel Fortran seem to work even without Line 4, but does this mean that move_alloc() automatically deallocates a(:) if it is pre-allocated? Second, can we replace Lines 1 and 2 by 3, i.e., use sourced allocation with different lengths of arrays? I have experimented this, and again, both gfortran and Intel Fortran seem to accept it with the (apparently) correct result.
From the Fortran standard (2008, 13.7.118) about move_alloc we have the detail of the argument to (the second argument of the subroutine)
It is an INTENT (OUT) argument
which matches the description you give in the link to the gfortran manual.
As for any other dummy argument with the intent(out) and allocatable attributes the actual argument associated with to, then, is deallocated on invoking the subroutine move_alloc. That is, you do not need to deallocate a yourself.
Regarding the sourced allocation, we already know that the array being allocated must be conformable with the source array, so that writing
allocate(buf(4), source=a) ! a is the same rank as buf, but extent 2
is invalid, just as much as
allocate(buf(4), source=a(1:2))
is.
However, whilst there are some numbered constraints about sourced allocation this conformable requirement doesn't feature in one of those. So, your compiler isn't required to detect that your code is non-conforming.
Naturally, a compiler is allowed to complain, as you see when using a(1:2) as the source. To some degree, it is much easier at compile-time to see that an array of extent 4 is not conformable with a(1:2) than the case of a. You can experiment with, say, a(1:SIZE(a)) to see just how much effort your compiler takes with such tests.
As a final comment, one can of course replace your lines 1 and 2 with a single sourced allocation:
allocate(buf, source=[a,0,0]) ! Buf is 2 longer than a
But that's not necessarily "better".
The Fortran standard is written so that you don't have to wory about memory leaks with allocatables. If the operation is not forbidden in the first place, it should not cause any leaks. This rule holds for any possible standard conforming operations with allocatable variables.
So, as the Intel manual states, the to argument will be deallocated first.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With