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.