Fortran の派生型中の動的割り付け成分の代入時の動作差
派生型中に、動的な配列を定義することができますが、allocatable で定義するか、pointer で定義するかで、代入時のコピーのされ方に違いが出ます。
allocatable の場合は、内容丸ごとコピーですが、これに対して pointer の場合は、(当然ですが)動的に確保した記憶領域の番地情報だけがコピーされます。つまり allocatable の場合は deep copy 、pointer の場合は shallow copy となります。
したがって、pointer で確保した場合は、派生型内の動的配列の実体は一つなのでその内容をいじると、代入した他の派生型変数でもその内容が変化します。一方、allocatble の場合、動的配列は新しく確保されて内容が写されるので変化しません。
代入コストから考えると pointer の場合はコストが小さいですが、allocatable の場合は新たにメモリー領域を確保したうえで内容を写し取るので、コストが大きいと言えます。
実行結果
allocatable component : deep copy 10 1 2 3 4 10 1 2 3 4 10 101 102 103 104 10 1 2 3 4 pointer component : shallow copy 10 4 3 2 1 10 4 3 2 1 10 100 99 98 97 10 100 99 98 97
プログラム
program test implicit none type :: t_alloc integer :: n integer, allocatable :: ia(:) end type t_alloc type t_point integer :: n integer, pointer :: ip(:) end type t_point type (t_alloc) :: a, b type (t_point) :: p, q a = t_alloc(10, [1, 2, 3, 4]) b = a ! print *, 'allocatable component : deep copy' print *, a%n, a%ia print *, b%n, b%ia a%ia = [101, 102, 103, 104] print *, a%n, a%ia print *, b%n, b%ia ! print * print *, 'pointer component : shallow copy' p%n = 10 allocate(p%ip(4), source = [4, 3, 2, 1]) q = p print *, p%n, p%ip print *, q%n, q%ip p%ip = [100, 99, 98, 97] print *, p%n, p%ip print *, q%n, q%ip end program test
- 作者: Michael Metcalf,John Reid,Malcolm Cohen
- 出版社/メーカー: Oxford Univ Pr
- 発売日: 2018/11/06
- メディア: ハードカバー
- この商品を含むブログを見る