问题
I am using gfortran 8.4 in Ubuntu with a deferred-length character variable as in the following example:
PROGRAM test
IMPLICIT NONE
CHARACTER(LEN=:),ALLOCATABLE :: str
str = '10'
END PROGRAM test
If I compile it using:
gfortran-8 test.f90 -o test -O0
When running the program using Valgrind I get a memory leak:
==29119== HEAP SUMMARY:
==29119== in use at exit: 2 bytes in 1 blocks
==29119== total heap usage: 22 allocs, 21 frees, 13,522 bytes allocated
==29119==
==29119== LEAK SUMMARY:
==29119== definitely lost: 2 bytes in 1 blocks
==29119== indirectly lost: 0 bytes in 0 blocks
==29119== possibly lost: 0 bytes in 0 blocks
==29119== still reachable: 0 bytes in 0 blocks
==29119== suppressed: 0 bytes in 0 blocks
However, compiling the program with:
gfortran-8 test.f90 -o test -O1
I get in Valgrind:
==29130== HEAP SUMMARY:
==29130== in use at exit: 0 bytes in 0 blocks
==29130== total heap usage: 21 allocs, 21 frees, 13,520 bytes allocated
==29130==
==29130== All heap blocks were freed -- no leaks are possible
I do not understand why I am getting this memory leak when no optimization is applied at compile time. Thanks in advance.
回答1:
It might not be perfectly nice to let the OS do the memory cleanup for a variable that has a lifetime until the end of a program, but it's still valid.
To avoid these false positive leaks in valgrind it is sufficient to enclose your code in a scope contained in the main program using the block
construct.
回答2:
All variables declared in the main program or as module variables are implicitly save
. Saved variables are not automatically deallocated. The Fortran standard does not mandate deallocation of arrays at the end of the program. They will be reclaimed by your OS anyway.
You can deallocate your arrays manually or if you wish to get automatic reallocation, you can move that logic - and the allocatable variables - into a subroutine that is entered from the main program. That way the local allocatable variables of that subroutine will be deallocated when the subroutine finishes.
Alternatively, you can also create a block using block
and end block
and declare the allocatable variables inside the block with all that it brings. They will be deallocated when the execution of the block is finished.
Technically what happens is that code generated by the compiler for your program does not maintain the pointers inside the allocatable descriptors until the moment valgrind would like to see them for them to be "still reachable". That is a technicality that you do not have to worry about.
来源:https://stackoverflow.com/questions/62410496/deferred-length-character-variable-causing-memory-leaks-depending-on-the-optimiz