Deferred-length character variable causing memory leaks depending on the optimization level

我是研究僧i 提交于 2020-07-30 06:58:11

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!