割り当て可能な配列#

allocatable 属性は、メモリ処理のための安全な方法を提供します。pointer 属性を持つ変数と比較して、メモリは自動的に管理され、変数がスコープ外になると自動的に解放されます。allocatable 変数を使用すると、アプリケーションでメモリリークを作成する可能性がなくなります。

サブルーチンで、自動配列がスタックに収まらないほど大きくなる場合に、スクラッチまたは作業用の配列を作成するために使用できます。

real(dp), allocatable :: temp(:)
allocate(temp(10))

割り当てステータスは、初期化されていないアクセスを避けるために allocated 組み込み関数を使用して確認できます。

subroutine show_arr(arr)
  integer, allocatable, intent(in) :: arr(:)

  if (allocated(arr)) then
    print *, arr
  end if
end subroutine show_arr

プロシージャ内で変数を割り当てるには、仮引数が allocatable 属性を持つ必要があります。intent(out) と組み合わせて使用すると、プロシージャに入る前に以前の割り当てが解放されます。

subroutine foo(lam)
  real(dp), allocatable, intent(out) :: lam(:)
  allocate(lam(5))
end subroutine foo

割り当てられた配列は、後で通常の配列のように使用できます。

real(dp), allocatable :: lam(:)
call foo(lam)

既に割り当てられている配列は、事前に解放しないと再度割り当てることはできません。同様に、解放は割り当てられた配列に対してのみ呼び出すことができます。配列を再割り当てするには、次を使用します。

if (allocated(lam)) deallocate(lam)
allocate(lam(10))

割り当てられた配列をプロシージャに渡す場合、仮引数に allocatable 属性はもう必要ありません。

subroutine show_arr(arr)
  integer, intent(in) :: arr(:)

  print *, arr
end subroutine show_arr

subroutine proc
  integer :: i
  integer, allocatable :: arr

  allocate(arr(5))

  do i = 1, size(arr)
    arr(i) = 2*i + 1
  end do
  call show_arr(arr)
end subroutine proc

このコンテキストで割り当てられていない配列を渡すと、無効なメモリアクセスにつながります。割り当て可能な配列は optional 仮引数に渡すことができます。割り当てられていない場合、引数は存在しません。allocatable 属性は配列に限定されず、スカラーに関連付けることもでき、optional 仮引数と組み合わせて使用すると便利です。

割り当ては、move_alloc 組み込みサブルーチンを使用して、allocatable 属性を持つ異なる配列間で移動できます。

subroutine resize(var, n)
  real(wp), allocatable, intent(inout) :: var(:)
  integer, intent(in), optional :: n
  integer :: this_size, new_size
  integer, parameter :: inital_size = 16

  if (allocated(var)) then
    this_size = size(var, 1)
    call move_alloc(var, tmp)
  else
    this_size = initial_size
  end if

  if (present(n)) then
    new_size = n
  else
    new_size = this_size + this_size/2 + 1
  end if

  allocate(var(new_size))

  if (allocated(tmp)) then
    this_size = min(size(tmp, 1), size(var, 1))
    var(:this_size) = tmp(:this_size)
  end if
end subroutine resize

最後に、割り当ては配列を初期化しません。初期化されていない配列の内容は、ほとんどの場合、それぞれの番地に以前あったバイトです。割り当ては、source属性を使用した初期化をサポートします。

real(dp), allocatable :: arr(:)
allocate(arr(10), source=0.0_dp)

source キーワードは、スカラー値と配列値の変数と定数をサポートします。