带有派生类型指针的代码是否会泄漏内存?

时间:2018-03-23 23:30:11

标签: fortran gfortran

我的IDE是Code :: Blocks 17.2,带有编译器GFortran 6.3.1

所有代码是:

PROGRAM EES_TEST

USE , NON_INTRINSIC :: DERIVED_TYPE

IMPLICIT NONE

INTEGER :: I , ALLOC_ERR , DEALLOC_ERR
LOGICAL :: GLOBAL_ERR

CLASS ( TRONA ) , POINTER :: P_TRA
TYPE ( TRONA ) , ALLOCATABLE , TARGET :: TRAN(:)

IF ( .NOT. ALLOCATED ( TRAN ) ) ALLOCATE ( TRAN ( 2 ) , STAT = ALLOC_ERR )

IF ( ALLOC_ERR .NE. 0 ) STOP ("PROBLEM WITH MEMORY ALLOCATION - TRAN!!!")

OPEN ( UNIT = 15 , FILE = 'INPUT.TXT' , ACTION = 'READ' )

  DO I = 1 , 2

     P_TRA => TRAN ( I )
     GLOBAL_ERR = P_TRA%UCI()

     IF ( GLOBAL_ERR .EQV. .TRUE. ) STOP ("ERROR WITH READING FROM OUTPUT.TXT!")

  END DO

CLOSE ( 15 )

IF ( ALLOCATED ( TRAN ) ) DEALLOCATE ( TRAN , STAT = DEALLOC_ERR )

IF ( DEALLOC_ERR .NE. 0 ) STOP ("PROBLEM WITH MEMORY DEALLOCATION - TRAN!!!")

END PROGRAM EES_TEST

MODULE DERIVED_TYPE

IMPLICIT NONE

TYPE , PUBLIC :: TRONA

  PRIVATE

    REAL :: Sn
    REAL :: Vn

  CONTAINS

    PROCEDURE , PUBLIC :: UCI => UCI_POD_TRONA
    PROCEDURE , PUBLIC :: TAKE_Sn => TAKE_POD_Sn
    PROCEDURE , PUBLIC :: TAKE_Vn => TAKE_POD_Vn

END TYPE TRONA

PRIVATE :: UCI_POD_TRONA
PRIVATE :: TAKE_POD_Sn , TAKE_POD_Vn

CONTAINS

  FUNCTION UCI_POD_TRONA ( THIS ) RESULT ( WRONG )

    IMPLICIT NONE

    CLASS ( TRONA ) :: THIS
    LOGICAL :: WRONG

    WRONG = .FALSE.

    READ ( 15 , * , ERR = 100 ) THIS%Sn
    READ ( 15 , * , ERR = 101 ) THIS%Vn

  RETURN

  100 WRITE (*,*) "WRONG FORMAT - INPUT 100!"
  WRONG = .TRUE.
  STOP

  101 WRITE (*,*) "WRONG FORMAT - INPUT 101!"
  WRONG = .TRUE.
  STOP

  END FUNCTION UCI_POD_TRONA

  FUNCTION TAKE_POD_Sn ( THIS ) RESULT ( POD_Sn )

    IMPLICIT NONE

    CLASS ( TRONA ) :: THIS
    REAL :: POD_Sn

    POD_Sn = THIS%Sn

  RETURN
  END FUNCTION TAKE_POD_Sn


  FUNCTION TAKE_POD_Vn ( THIS ) RESULT ( POD_Vn )

    IMPLICIT NONE

    CLASS ( TRONA ) :: THIS
    REAL :: POD_Vn

    POD_Vn = THIS%Vn

  RETURN
  END FUNCTION TAKE_POD_Vn

END MODULE DERIVED_TYPE

我是Fortran中面向对象编程的新手,所以我需要一个关于使用对象指针从派生类型调用方法的解释。在这种情况下,我想检查内存泄漏是否有任何问题,如果是这种情况,是否有方法检查有多少内存丢失和在哪一行?另一件事是使派生类型指针无效。如何为这种情况做到这一点?

1 个答案:

答案 0 :(得分:2)

通常,除非您在某处分配某些内容,否则无法发生内存泄漏。这根本不可能。你只能泄漏你指定为指针目标的东西,没有别的。

在您的代码中,指针没有allocate(),因此不会有任何内存泄漏。

要发生内存泄漏,必须按顺序执行两项操作。

  1. 必须分配匿名指针目标。这只能通过allocate语句

    实现
    allocate(p_tra)
    
  2. 指向目标的指针丢失。要么将其重定向到其他地方

    p_tra => somewhere_else
    

    或者它不再存在,因为它是一个完成的子程序的局部变量,或者它是一个被解除分配或类似的结构的一个组成部分......

  3. 您始终可以使用GCC清理-fssnitize=leakvalgrind来检查内存泄漏。

    关于nulifying,只需使用nulify语句或分配给null()。它是一个像任何其他指针一样的指针。

    p_tra => null()