- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I found a memory leak with Intel Inspector XE 2011 when analyzing a fortran program compiled with compiler version:
Intel Visual Fortran Compiler XE for applications running on IA-32, Version 12.1.3.300 Build 20120130
After studying the problem I managed to produce a minimal example (at the end of the post).
I compiled the program with option /debug:full and analyzed it with Inspector. The result is that the memory allocated at line 23 (subroutine SET_ID) which is called from line 51 is not freed. Total of 2 bytes. There were no other memory leaks, which implies that the component OBJ of the TYPE(CONTAINER_T) is actually deallocated, but the finalization is not done.
If the explicit deallocation (commented line 56) is run the finalization occurs and Inspector is happy to report "no problems detected".
This behavior is a bit surprising. I tried to see what the FORTRAN 2003 standard says and found out that the CONTAINER_T itself is not finalizable. Quote from the standard (section 4.5.5, lines 21-22):
"A derived type is finalizable if it has any final subroutines or if it has any nonpointer, nonallocatable component whose type is finalizable."
However, even if the type itself is not finalizable I would expect that the automatic deallocation of the allocatable subcomponent would cause the same finalization procedure to occur as explicitly calling DEALLOCATE.
Regards,
-Heikki
[fortran]MODULE FINALIZABLE IMPLICIT NONE TYPE :: FINALIZABLE_T PRIVATE CHARACTER(LEN=:), POINTER :: ID => NULL() CONTAINS PROCEDURE :: SET_ID FINAL :: FINALIZE END TYPE TYPE :: CONTAINER_T TYPE(FINALIZABLE_T), ALLOCATABLE :: OBJ(:) END TYPE CONTAINS SUBROUTINE SET_ID( THIS, ID ) CLASS(FINALIZABLE_T) :: THIS CHARACTER(LEN=*), INTENT(IN) :: ID IF ( ASSOCIATED( THIS % ID ) ) DEALLOCATE( THIS % ID ) ALLOCATE( THIS % ID, SOURCE = ID ) END SUBROUTINE ELEMENTAL SUBROUTINE FINALIZE( THIS ) TYPE(FINALIZABLE_T), INTENT(INOUT) :: THIS IF ( ASSOCIATED( THIS % ID ) ) DEALLOCATE( THIS % ID ) END SUBROUTINE END MODULE MODULE FINALIZATION_TEST USE FINALIZABLE IMPLICIT NONE CONTAINS SUBROUTINE TEST TYPE(FINALIZABLE_T), ALLOCATABLE :: A(:) TYPE(CONTAINER_T) :: B INTEGER :: I DO I = 1, SIZE(A) CALL A(I) % SET_ID( 'A' ) END DO ALLOCATE( B % OBJ(2) ) DO I = 1, SIZE(B % OBJ) CALL B % OBJ(I) % SET_ID( 'B' ) END DO ! without explicit deallocation the finalization is not done ! memory leak is fixed by uncommenting following line !DEALLOCATE( B % OBJ ) END SUBROUTINE END MODULE PROGRAM TEST_PROGRAM USE FINALIZATION_TEST IMPLICIT NONE CALL TEST END PROGRAM [/fortran]
Intel Visual Fortran Compiler XE for applications running on IA-32, Version 12.1.3.300 Build 20120130
After studying the problem I managed to produce a minimal example (at the end of the post).
I compiled the program with option /debug:full and analyzed it with Inspector. The result is that the memory allocated at line 23 (subroutine SET_ID) which is called from line 51 is not freed. Total of 2 bytes. There were no other memory leaks, which implies that the component OBJ of the TYPE(CONTAINER_T) is actually deallocated, but the finalization is not done.
If the explicit deallocation (commented line 56) is run the finalization occurs and Inspector is happy to report "no problems detected".
This behavior is a bit surprising. I tried to see what the FORTRAN 2003 standard says and found out that the CONTAINER_T itself is not finalizable. Quote from the standard (section 4.5.5, lines 21-22):
"A derived type is finalizable if it has any final subroutines or if it has any nonpointer, nonallocatable component whose type is finalizable."
However, even if the type itself is not finalizable I would expect that the automatic deallocation of the allocatable subcomponent would cause the same finalization procedure to occur as explicitly calling DEALLOCATE.
Regards,
-Heikki
[fortran]MODULE FINALIZABLE IMPLICIT NONE TYPE :: FINALIZABLE_T PRIVATE CHARACTER(LEN=:), POINTER :: ID => NULL() CONTAINS PROCEDURE :: SET_ID FINAL :: FINALIZE END TYPE TYPE :: CONTAINER_T TYPE(FINALIZABLE_T), ALLOCATABLE :: OBJ(:) END TYPE CONTAINS SUBROUTINE SET_ID( THIS, ID ) CLASS(FINALIZABLE_T) :: THIS CHARACTER(LEN=*), INTENT(IN) :: ID IF ( ASSOCIATED( THIS % ID ) ) DEALLOCATE( THIS % ID ) ALLOCATE( THIS % ID, SOURCE = ID ) END SUBROUTINE ELEMENTAL SUBROUTINE FINALIZE( THIS ) TYPE(FINALIZABLE_T), INTENT(INOUT) :: THIS IF ( ASSOCIATED( THIS % ID ) ) DEALLOCATE( THIS % ID ) END SUBROUTINE END MODULE MODULE FINALIZATION_TEST USE FINALIZABLE IMPLICIT NONE CONTAINS SUBROUTINE TEST TYPE(FINALIZABLE_T), ALLOCATABLE :: A(:) TYPE(CONTAINER_T) :: B INTEGER :: I DO I = 1, SIZE(A) CALL A(I) % SET_ID( 'A' ) END DO ALLOCATE( B % OBJ(2) ) DO I = 1, SIZE(B % OBJ) CALL B % OBJ(I) % SET_ID( 'B' ) END DO ! without explicit deallocation the finalization is not done ! memory leak is fixed by uncommenting following line !DEALLOCATE( B % OBJ ) END SUBROUTINE END MODULE PROGRAM TEST_PROGRAM USE FINALIZATION_TEST IMPLICIT NONE CALL TEST END PROGRAM [/fortran]
Link Copied
1 Reply
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I studied the Fortran 2003 standard a bit more. It seems to me that in this case the finalization should occur even without the explicit deallocate. Please correct me, if I'm wrong.
The fortran standard states that: "When an allocatable entity is deallocated, it is finalized." (Section 4.5.5.2)
The finalization according to the standard should do the following: "... if there is an elemental final subroutine whose dummy argument has the same kind type parameters as the entity being finalized, it is called with the entity as an actual argument." (Section 4.5.5.1)
In this case there is an elemental final subroutine that matches the above condition. It seems that in this case the compiled code does not work according to the standard.
Regards,
-Heikki
The fortran standard states that: "When an allocatable entity is deallocated, it is finalized." (Section 4.5.5.2)
The finalization according to the standard should do the following: "... if there is an elemental final subroutine whose dummy argument has the same kind type parameters as the entity being finalized, it is called with the entity as an actual argument." (Section 4.5.5.1)
In this case there is an elemental final subroutine that matches the above condition. It seems that in this case the compiled code does not work according to the standard.
Regards,
-Heikki

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page