Unlike some other languages, an array allocated in a Fortran subprogram is automatically deallocated when the subprogram returns.
To some extent, this has the advantage of preventing memory leaks, where a programmer allocates more and more memory over time and forgets to deallocate all of it, resulting in a continual reduction in available memory. Automatically deallocating arrays does not completely eliminate memory leaks however, and some might argue that it leads to less disciplined programmers by allowing them to be less vigilant.
Automatically deallocating arrays when a subprogram returns is sometimes a disadvantage as well. There are situations where we want a subprogram to allocate memory which can later be used by the calling subprogram, or others. In Fortran, however, allocated memory is only accessible to the subprogram that allocated it, and other subprograms called by it after the allocation and before it returns. Consider the following read\_list() implementation:
! Main program body program cant_do_this ! Disable implicit declarations (i-n rule) implicit none ! Variable defintions integer :: num_temps real(8), allocatable :: temps(:) ! Allocate an array for a list of temps and fill it from input ! Get back the list and the list size from read_list() call read_list(temps, num_temps) ! Print the list returned by read_list end program subroutine read_list(list, list_size) ! Disable implicit declarations (i-n rule) implicit none ! Dummy variables ! Define list_size first, since it is used to define list integer, intent(out) :: list_size real(8), intent(out), allocatable :: list(:) ! Local variables integer :: i, alloc_status read *, list_size allocate(list(1:list_size), stat=alloc_status) if ( alloc_status /= 0 ) then print *, 'Allocate failed. status = ', alloc_status stop endif do i = 1, list_size read *, list(i) enddo end subroutine
The code above will compile, but will not work, because the array allocated inside the read_list() subroutine is deallocated when the subroutine returns. Hence, the array no longer exists after coming back to the main program from read_list().
The code below shows how this task must be accomplished in Fortran. The array must be allocated before calling read_list() and passed to read_list() to receive the input. The array can exist in the main program, in read_list(), and in other subprograms called by the main program.
! Main program body program this_one_works ! Disable implicit declarations (i-n rule) implicit none ! Variable defintions integer :: num_temps, alloc_status real(8), allocatable :: temps(:) read *, num_temps allocate(temps(1:num_temps), stat=alloc_status) if ( alloc_status /= 0 ) then print *, 'Allocate failed. status = ', alloc_status stop endif ! Allocate an array for a list of temps and fill it from input ! Get back the list and the list size from read_list() call read_list(temps, num_temps) ! Print the list returned by read_list end program subroutine read_list(list, list_size) ! Disable implicit declarations (i-n rule) implicit none ! Dummy variables ! Define list_size first, since it is used to define list integer, intent(in) :: list_size real(8), intent(out) :: list(1:list_size) ! Local variables integer :: i do i = 1, list_size read *, list(i) enddo end subroutine
In C, memory allocated by malloc() remains allocated until it is released by free(). This is part of the C philosophy of "trust the programmer". This philosophy often leads to programmers shooting themselves in the foot, but also allows programmers to easily do what they need to.