-
Notifications
You must be signed in to change notification settings - Fork 10
Description
In Fortran, it is possible to create an array with
real*8, dimension(:), pointer :: vec
allocate(vec(100))
the effect of this code is to allocate an array, and associate the pointer vec
to it. Unfortunately, since it is a pointer, it will not be automatically deallocated when it goes out of scope, and therefore could cause a memory leak. A safer way of allocating an array is
real*8, dimension(:), allocatable :: vec2
allocate(vec2(100))
Unfortunately, it is not just a matter of replacing pointer
with allocatable
, since there are also other steps.
First of all, we must distinguish, which arrays can become allocatable from the ones that must remain pointers. Consider the following example
real*8, dimension(:), pointer :: vec
real*8, dimension(:), pointer :: p_vec
allocate(vec(100))
p_vec => vec(20:50)
In this case, only vec
should become an allocatable.
Since it is good practice to nullify pointers (otherwise their status is undefined), there might be a bunch of vec=>null()
and nullify(vec)
, which must be deleted.
Next, the code might contain several if (associated(vec))
, which must be replaced with if (allocated(vec))
.
The last thing to address is that when a pointer is associated to an allocatable, that allocatable needs the target
attribute. For example
real*8, dimension(:), allocatable, target :: vec2
real*8, dimension(:), pointer :: p_vec
allocate(vec2(100))
p_vec => vec2(20:50)
A slightly more complex case is
type t_special
real*8 :: a
real*8, dimension(:), allocatable :: b
end t_special
type(t_special), dimension(:), allocatable, target :: c
type(t_special), dimension(:), pointer :: p_c
allocate(c(15))
p_c => c
Note that in this case the target
attribute is applied to c
, and not to the fields of the derived type.