我的带有派生类型指针的代码会泄漏内存吗?
Does my code with derived type pointers leak memory?
我的 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 面向对象编程的新手,因此我需要有关使用对象指针从派生类型调用方法的解释。在这种情况下,我想检查内存泄漏是否有任何问题,如果是,是否有方法检查丢失了多少内存以及在哪一行?另一件事是使派生类型指针无效。这种情况下该怎么做?
通常,除非您在某处分配了一些东西,否则您不会有内存泄漏。这根本不可能。你只能泄漏你分配为指针目标的东西,没有别的。
在您的代码中没有 allocate()
指针,因此不会有任何内存泄漏。
要发生内存泄漏,必须依次发生两件事。
必须分配匿名指针目标。这只能通过分配语句
allocate(p_tra)
指向目标的指针丢失。要么它被重定向到其他地方
p_tra => somewhere_else
或者它不再存在,因为它是一个完成的子程序的局部变量,或者它是一个被释放或类似的结构的组件...
您始终可以使用 GCC 清理 -fssnitize=leak
或 valgrind
来检查内存泄漏。
关于无效化,只需使用nulify
语句或赋值给null()
。它和其他指针一样。
p_tra => null()
我的 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 面向对象编程的新手,因此我需要有关使用对象指针从派生类型调用方法的解释。在这种情况下,我想检查内存泄漏是否有任何问题,如果是,是否有方法检查丢失了多少内存以及在哪一行?另一件事是使派生类型指针无效。这种情况下该怎么做?
通常,除非您在某处分配了一些东西,否则您不会有内存泄漏。这根本不可能。你只能泄漏你分配为指针目标的东西,没有别的。
在您的代码中没有 allocate()
指针,因此不会有任何内存泄漏。
要发生内存泄漏,必须依次发生两件事。
必须分配匿名指针目标。这只能通过分配语句
allocate(p_tra)
指向目标的指针丢失。要么它被重定向到其他地方
p_tra => somewhere_else
或者它不再存在,因为它是一个完成的子程序的局部变量,或者它是一个被释放或类似的结构的组件...
您始终可以使用 GCC 清理 -fssnitize=leak
或 valgrind
来检查内存泄漏。
关于无效化,只需使用nulify
语句或赋值给null()
。它和其他指针一样。
p_tra => null()