内存分配和单独模块中的释放

时间:2017-10-26 11:21:27

标签: fortran gfortran

这是我的代码:

Program Dynamic_Array

Use Variables
Use Allocation_Module
Use Dealloaction_Module

Implicit none

Call Subroutine_0

Call Subroutine_1

End Program Dynamic_Array

Module Variables

Implicit none

Integer :: i , k
Integer , parameter :: Br_sn_cvo = 10
Integer , parameter :: Br_nn_mre = 7
Integer , parameter , dimension ( Br_nn_mre) :: Br_nn_cvo = [ 7 , 6 , 5 , 4 , 3 , 2 , 1 ]
Integer , dimension ( Br_nn_mre ) :: i_nn_dm_1 , i_nn_dm_2

type :: my_type

     integer, allocatable :: my_size(:)

end type my_type

type(my_type), allocatable :: dS_sn(:)

End Module Variables

Module Allocation_Module

Use Variables

Implicit none

Contains

Subroutine Subroutine_0

Allocate(dS_sn(Br_nn_mre))

Loop_1: Do k = 1, Br_nn_mre

        i_nn_dm_1(k) = Br_sn_cvo + Br_nn_mre + 1 + Br_nn_cvo(k) * ( k - 1 )
        i_nn_dm_2(k) = Br_sn_cvo + Br_nn_mre + k * Br_nn_cvo(k)

        Allocate( dS_sn(k)%my_size( i_nn_dm_1(k) : i_nn_dm_2(k)) )

        Loop_2: Do i = i_nn_dm_1(k) , i_nn_dm_2(k)

                   dS_sn(k)%my_size(i) = i + k

                End Do Loop_2

        End do loop_1

End subroutine Subroutine_0

End Module Allocation_Module

Module Dealloaction_Module

Use Variables

Implicit none

Contains

Subroutine Subroutine_1

Do k = 1 , Br_nn_mre

   Deallocate(dS_sn(k)%my_size)

End do

   Deallocate(dS_sn)

Return
End Subroutine Subroutine_1

End Module Dealloaction_Module

我在Fortran中没有经验丰富的程序员,所以我需要问一些关于动态数组的内存分配和释放过程的问题。此代码中是否存在内存泄漏问题? 这是在单独模块中进行内存分配的正确方法吗? 这是在单独的模块中进行内存释放的正确方法吗?

2 个答案:

答案 0 :(得分:1)

这是一个例子......

...

IF(ALLOCATED(TheArray)) THEN
  IF(SIZE(TheArray) /= The_Size_I_need) DEALLOCATE(TheArray)
ENDIF
IF(.NOT.  ALLOCATED(TheArray)) ALLOCATE(TheArray(The_Size_I_need))

如果对不同的处理大小重复使用该数组,这将非常有用。

如果根据当前执行“始终”修复它,那么就没有必要做任何事情。

答案 1 :(得分:0)

代码中没有内存泄漏。在Fortran中使用allocatable实体进行内存泄漏是不可能的。只有pointer会导致内存泄漏。

如果某些东西超出范围,则使用allocatable,它会自动解除分配。

您的主数组是一个模块变量,因此它永远不会超出范围(Fortran 2008规则隐含地save)。因此,如果您不自行解除分配,它将保持分配状态,然后由程序终止的操作系统删除。但那通常被认为是 是内存泄漏。它并没有真正的危害,因为没有办法在内存中制作一些被遗忘的数组副本。

取消分配大型数组my_size时,各个组件dS_sn可能超出范围。在这种情况下,它们会被Fortran规则自动解除分配。你不必逐个解除分配。

所以你真的不必做

Do k = 1 , Br_nn_mre

   Deallocate(dS_sn(k)%my_size)

End do

只做

Deallocate(dS_sn)

完全正确。