-
Notifications
You must be signed in to change notification settings - Fork 12
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 => cNote that in this case the target attribute is applied to c, and not to the fields of the derived type.