fortran66のブログ

fortran について書きます。

【メモ帳】target 付き allocatable の解放

unique pointer としての allocatable

Fortran 90 で導入された allocatable 属性は、F90 の時点では自動解放されず、他の変数に associate 出来ないだけで pointer と大して変わりないものでした。Fortran 95 で subroutine/function の副プログラムから出る時に、その中で定義した allocatable 変数は自動解放するようになって安全・安心wになりました。また move_alloc subroutine も導入され、pointer 的な shallow copy も可能としました。( Fortran 2008 からは、新たに導入された block 構造を抜ける時にも block 内で定義した allocatable 変数は自動解放されます。)

当初、Fortran の allocatble は、普通の科学者・技術者ごときには高邁なる pointer が理解できないだろうからと導入されたものでしたが、30年近くたって今をときめく流行りの新言語では生の pointer が否定されるようになり、安全性を高めた allocatable 的なものが自画自賛されながら導入されているのが面白いところです。

Fortran の allocatable は、target 属性を付けると pointer で associate 出来るようになり、確保先の heap の番地先が unique でなくなります。この場合 pointer が allocatable 変数に associate されていると、allocatable 変数の自動解放が行われた後 associate 先が存在しないことになります。(pointer 型の変数に associate した場合は、pointer 変数は自動解放されないので associate 先が残りますが手動で解放する必要があります。

Modern Fortran: Building efficient parallel applications

Modern Fortran: Building efficient parallel applications

  • 作者:Curcic, Milan
  • 発売日: 2020/11/24
  • メディア: ペーパーバック

allocatable

    program unique2
        implicit none
        integer :: i
        real, pointer :: p(:)
        block
           real, allocatable, target :: a(:)
    !        real, pointer :: a(:)
            allocate(a(10**8))
            a = 9.9999
            p => a
            print *, size(a)
            pause
        end block  
        print *, size(p), associated(p)
        print *, (p(1:10))
        pause
    end program unique2
   100000000
Fortran Pause - Enter command<CR> or <CR> to continue.

   100000000 T
forrtl: 致命的なエラー (157): プログラム例外 - アクセス違反
Image              PC                Routine            Line        Source
unique2.exe        00007FF6F25B1745  MAIN__                     15  unique2.f90
unique2.exe        00007FF6F25B17EE  Unknown               Unknown  Unknown
unique2.exe        00007FF6F25B4329  Unknown               Unknown  Unknown
unique2.exe        00007FF6F25B424E  Unknown               Unknown  Unknown
unique2.exe        00007FF6F25B410E  Unknown               Unknown  Unknown
unique2.exe        00007FF6F25B439E  Unknown               Unknown  Unknown
KERNEL32.DLL       00007FFCD9A27034  Unknown               Unknown  Unknown
ntdll.dll          00007FFCDBA02651  Unknown               Unknown  Unknown

pointer

    program unique2
        implicit none
        integer :: i
        real, pointer :: p(:)
        block
    !       real, allocatable, target :: a(:)
            real, pointer :: a(:)
            allocate(a(10**8))
            a = 9.9999
            p => a
            print *, size(a)
            pause
        end block
        print *, size(p), associated(p)
        print *, (p(1:10))
        deallocate(p)
        pause
    end program unique2
   100000000
Fortran Pause - Enter command<CR> or <CR> to continue.

   100000000 T
   9.999900       9.999900       9.999900       9.999900       9.999900
   9.999900       9.999900       9.999900       9.999900       9.999900
Fortran Pause - Enter command<CR> or <CR> to continue.

続行するには何かキーを押してください . . .