Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Memory leaks 延迟长度字符变量导致内存泄漏,具体取决于优化级别_Memory Leaks_Fortran_Gfortran - Fatal编程技术网

Memory leaks 延迟长度字符变量导致内存泄漏,具体取决于优化级别

Memory leaks 延迟长度字符变量导致内存泄漏,具体取决于优化级别,memory-leaks,fortran,gfortran,Memory Leaks,Fortran,Gfortran,我在Ubuntu中使用gfortran 8.4,带有延迟长度字符变量,如下例所示: PROGRAM test IMPLICIT NONE CHARACTER(LEN=:),ALLOCATABLE :: str str = '10' END PROGRAM test 如果我使用以下方法编译它: gfortran-8 test.f90 -o test -O0 使用Valgrind运行程序时,我发现内存泄漏: ==29119== HEAP SUMMARY: ==29119==

我在Ubuntu中使用gfortran 8.4,带有延迟长度字符变量,如下例所示:

PROGRAM test
   IMPLICIT NONE
   CHARACTER(LEN=:),ALLOCATABLE :: str 
   str = '10'
END PROGRAM test
如果我使用以下方法编译它:

gfortran-8 test.f90 -o test -O0
使用Valgrind运行程序时,我发现内存泄漏:

==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
但是,在编译程序时应使用:

gfortran-8 test.f90 -o test -O1
我进入瓦尔格林:

==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

我不明白为什么在编译时没有应用优化时会出现内存泄漏。提前感谢。

让操作系统为一个生命周期直到程序结束的变量进行内存清理可能不是很好,但它仍然有效


为了避免valgrind中的这些误报泄漏,使用
构造将代码封装在主程序中包含的范围内就足够了。

主程序中声明的或作为模块变量的所有变量都隐式地
保存
。保存的变量不会自动取消分配。Fortran标准不要求在程序结束时释放数组。无论如何,它们都将被您的操作系统回收

您可以手动取消分配数组,或者如果希望自动重新分配,可以将该逻辑(以及可分配变量)移动到从主程序输入的子例程中。这样,当子例程完成时,该子例程的本地可分配变量将被释放

或者,您也可以使用
block
end block
创建块,并声明块内的可分配变量及其带来的所有内容。当块的执行完成时,它们将被释放


从技术上讲,编译器为您的程序生成的代码不会在可分配描述符中维护指针,直到valgrind希望看到它们“仍然可以访问”为止。这是一个你不必担心的技术性问题。

(只是头脑中的一些想法)可能使用
-O1
时,代码被优化了,因为它没有被使用,而使用
-O0
时,根本没有进行优化。试着在赋值后放置一个
write(*,*)str
,看看会发生什么。你是对的,使用-O1代码会被优化掉,这就是为什么它不会显示内存泄漏。在任何情况下,我都不明白为什么会发生内存泄漏。显然,valgrind在结束之前看到了内存中剩余的内容,没有发生任何释放(str仍在范围内)。正如人们可能怀疑的那样,这是valgrind的检测问题,而不是gfortran对非泄漏程序的解释问题。valgrind不理解Fortran编译器生成的可执行文件。但请注意,在更一般的情况下,以这种方式使用块构造可能会改变程序的含义。