Tablice możliwe do przydzielenia#

Atrybut allocatable pozwala na bezpieczną obsługę pamięci. W porównaniu z atrybutem zmiennych pointer pamięć jest obsługiwana automatycznie i zostanie zwolniona w momencie, gdy zmienna wyjdzie poza zakres. Używanie atrybutu allocatable dla zmiennych zmniejsza prawdopodobieństwo powstania przecieków pamięci w aplikacji.

Mogą być używane w podprogramach, aby stworzyć tablice podstawowe lub robocze, gdzie automatyczne tablice mogłyby stać się zbyt duże, aby zmieścić się na stosie.

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

Status przydziału można sprawdzić za pomocą funkcji allocated, aby uniknąć niezainicjowanego dostępu

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

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

Aby przydzielić zmienne wewnątrz procedury fikcyjny argument musi posiadać atrybut allocatable. Użycie go w połączeniu z intent(out) zwolni poprzednie przydziały zanim rozpocznie się wykonywanie procedury:

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

Przydzielona tablica może być później używana jak normalna tablica

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

Przydzielona już tablica nie może zostać przydzielona ponownie bez wcześniejszego zwolnienia przydziału. Zwolnienie przydziału również może być rozpoczęte tylko dla przydzielonych już tablic. Aby zmienić przydział tablicy użyj

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

Przekazywanie przydzielonych tablic do procedur nie wymaga już użycia atrybutu allocatable dla fikcyjnego argumentu.

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

Przekazywanie nieprzydzielonej tablicy w tym kontekście doprowadzi do niepoprawnego dostępu do pamięci. Przydzielone tablice mogą być przekazywane do opcjonalnych (optional) argumentów fikcyjnych - w przypadku nieprzydzielenia tablicy argument nie będzie obecny. Atrybut allocatable nie jest ograniczony tylko do tablic i może być używany również do wielkości skalarnych, co może być przydatne w połączeniu z opcjonalnymi ( optional) argumentami fikcyjnymi.

Przydziały mogą być zmieniane pomiędzy różnymi tablicami przy użyciu atrybutu allocatable oraz wewnętrznego podprogramu move_alloc.

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

Na koniec, przydziały nie inicjują tablic. Zawartością niezainicjowanej tablicy są prawdopodobnie bajty tego, co poprzednio znajdowało się pod tym adresem. Przydziały obsługują inicjalizację przy użyciu atrybutu source:

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

Słowo kluczowe source obsługuje wartości skalarne, zmienne oraz stałe.