Share allocatable Arrays

后端 未结 3 883
离开以前
离开以前 2021-01-23 01:06

I have some allocatable arrays which I need to share between some subroutines. I usually would just pass them as arguments or maybe write everything in a Module, but I\'m afraid

3条回答
  •  暗喜
    暗喜 (楼主)
    2021-01-23 01:55

    The three examples below all work with gfortran. The second may fail on some compilers as it uses a F2003 feature (allocatable dummy arguments), and not all compilers are 100% F2003 compliant. However, most implement ISO TR 15581 (which includes this feature).

    First version, you can use a common pointer to allocatable array.

    program hip
       implicit none
       double precision, dimension(:, :), pointer :: p
       common /hiphop/ p
       double precision, allocatable, dimension(:, :), target :: a
       allocate(a(100, 100))
       a(1, 1) = 3.1416d0
       p => a
       call hop
       deallocate(a)
    end program
    
    subroutine hop
       implicit none
       double precision, dimension(:, :), pointer :: p
       common /hiphop/ p
       print *, size(p, 1), size(p, 2), p(1, 1)
    end subroutine
    

    Second version, allocating in a subroutine then calling another. One still needs to declare the array in main program.

    program hip
       implicit none
    
       interface
          subroutine hip_alloc(arr)
             double precision, allocatable, dimension(:, :) :: arr
          end subroutine
       end interface
    
       double precision, dimension(:, :), pointer :: p
       common /hiphop/ p
       double precision, allocatable, dimension(:, :) :: a
       p => null()
       print *, "a:", allocated(a)
       print *, "p:", associated(p)
       call hip_alloc(a)
       print *, "a:", allocated(a)
       print *, "p:", associated(p)
       call hop
       deallocate(a)
    end program
    
    subroutine hip_alloc(arr)
       implicit none
       double precision, dimension(:, :), pointer :: p
       common /hiphop/ p
       double precision, allocatable, dimension(:, :), target :: arr
       allocate(arr(100, 100))
       arr(1, 1) = 3.1416d0
       p => arr
    end subroutine
    
    subroutine hop
       implicit none
       double precision, dimension(:, :), pointer :: p
       common /hiphop/ p
       print *, size(p, 1), size(p, 2), p(1, 1)
    end subroutine
    

    Third version, here we first call a function returning a pointer, then pass this pointer to a subroutine through a common. The function does the allocation, as in second example. The pointer is deallocated in main program, but could be elsewhere.

    program hip
       implicit none
    
       interface
          function hip_alloc(n)
             integer :: n
             double precision, dimension(:, :), pointer :: hip_alloc
          end function
       end interface
    
       double precision, dimension(:, :), pointer :: p
       common /hiphop/ p
       p => null()
       print *, "p:", associated(p)
       p => hip_alloc(100)
       print *, "p:", associated(p)
       call hop
       deallocate(p)
    end program
    
    function hip_alloc(n)
       implicit none
       integer :: n
       double precision, dimension(:, :), pointer :: hip_alloc
       allocate(hip_alloc(n, n))
       hip_alloc(1, 1) = 3.1416d0
    end function
    
    subroutine hop
       implicit none
       double precision, dimension(:, :), pointer :: p
       common /hiphop/ p
       print *, size(p, 1), size(p, 2), p(1, 1)
    end subroutine
    

提交回复
热议问题