分配带有返回值的可分配多态变量时发生内存泄漏

问题描述 投票:1回答:1

我在内存管理或面向对象的Fortran 2008的正确使用方面苦苦挣扎。我的代码具有多个派生类型,并且它们的同一个父级(此处为Example01Example02)存储在Example_Class模块中。我想根据某个变量(此处为workenv)在子例程idx_example中加载一个示例。选择的任何一个都应该由基类中定义的过程访问,因此无论call active_Example%Info()是什么,我都可以执行active_Example

以下使用ifort(19.0.1.144)或gfortran(7.5.0)编译的代码按预期工作。但是valgrind(3.13.0)警告内存泄漏(请参见下面的代码)。如何防止内存泄漏并具有相同或相似的功能? (我想在Example_class模块中拥有控件,并且在if子例程中不使用多个workenv条件。]

module Example_Baseclass
   implicit none
   private
   public :: Examples
   type :: Examples
      character(len=20) :: name = ''
   contains
      private
      procedure, public :: Info
   end type
contains
   subroutine Info(this)
      class(Examples) :: this
      write(*,*) this%name
   end subroutine
end module

module Example_Class
   use Example_Baseclass
   implicit none
   private
   public :: Select_Example, Examples
   type, extends(Examples) :: Example01
   end type
   type, extends(Examples) :: Example02
   end type
contains
   function Select_Example(idx_example) result(myExample)
      integer, intent(in) :: idx_example
      class(Examples), allocatable :: myExample
      if (idx_example == 1) then
         allocate(Example01::myExample)
         myExample%name = 'Example Class 01'
      else
         allocate(Example02::myExample)
         myExample%name = 'Example Class 02'
      end if
   end function
end module

subroutine workenv(idx_example)
   use Example_Class
   implicit none
   integer, intent(in) :: idx_example
   class(Examples), allocatable :: active_Example
   active_Example = Select_Example(idx_example)
   call active_Example%Info()
end subroutine

program testprog
   implicit none
   integer :: idx_example
   idx_example = 2
   call workenv(idx_example)
end program

使用ifort -free -stand f08 Examples.f -o Examples时可以观察到

valgrind ./Examples
==1689== Memcheck, a memory error detector
==1689== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1689== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==1689== Command: ./Examples
==1689== 
==1689== Conditional jump or move depends on uninitialised value(s)
==1689==    at 0x48CFC1: __intel_sse2_strcpy (in /mnt/Data/Examples)
==1689==    by 0x45680E: for__add_to_lf_table (in /mnt/Data/Examples)
==1689==    by 0x43C363: for__open_proc (in /mnt/Data/Examples)
==1689==    by 0x42194D: for__open_default (in /mnt/Data/Examples)
==1689==    by 0x42C092: for_write_seq_lis (in /mnt/Data/Examples)
==1689==    by 0x40304D: example_baseclass_mp_info_ (in /mnt/Data/Examples)
==1689==    by 0x402E17: MAIN__ (in /mnt/Data/Examples)
==1689==    by 0x402A81: main (in /mnt/Data/Examples)
==1689== 
 Example Class 02    
==1689== 
==1689== HEAP SUMMARY:
==1689==     in use at exit: 32 bytes in 1 blocks
==1689==   total heap usage: 11 allocs, 10 frees, 12,775 bytes allocated
==1689== 
==1689== LEAK SUMMARY:
==1689==    definitely lost: 0 bytes in 0 blocks
==1689==    indirectly lost: 0 bytes in 0 blocks
==1689==      possibly lost: 0 bytes in 0 blocks
==1689==    still reachable: 32 bytes in 1 blocks
==1689==         suppressed: 0 bytes in 0 blocks
==1689== Rerun with --leak-check=full to see details of leaked memory
==1689== 
==1689== For counts of detected and suppressed errors, rerun with: -v
==1689== Use --track-origins=yes to see where uninitialised values come from
==1689== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

使用gfortran -ffree-form -std=f2008 Examples.f -o Examples

valgrind ./Examples
==1729== Memcheck, a memory error detector
==1729== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1729== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==1729== Command: ./Examples
==1729== 
 Example Class 02    
==1729== 
==1729== HEAP SUMMARY:
==1729==     in use at exit: 20 bytes in 1 blocks
==1729==   total heap usage: 23 allocs, 22 frees, 13,536 bytes allocated
==1729== 
==1729== LEAK SUMMARY:
==1729==    definitely lost: 20 bytes in 1 blocks
==1729==    indirectly lost: 0 bytes in 0 blocks
==1729==      possibly lost: 0 bytes in 0 blocks
==1729==    still reachable: 0 bytes in 0 blocks
==1729==         suppressed: 0 bytes in 0 blocks
==1729== Rerun with --leak-check=full to see details of leaked memory
==1729== 
==1729== For counts of detected and suppressed errors, rerun with: -v
==1729== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
memory-leaks fortran valgrind
1个回答
0
投票
我有一个类似的问题,我的父类型是抽象类型。我有一个函数返回可分配的多态对象。尽管结果与预期的一样,但是当使用gfortran编译时,valgrind会显示一些内存泄漏。英特尔没有显示出这样的问题。该线程可能也对您有帮助:https://gcc.gnu.org/bugzilla//show_bug.cgi?id=80477该错误已在2014年报告,但我想他们尚未修复。我有一个后续问题,您是否有与您的派生类型相关的任何终结程序?原则上,可分配对象在超出范围时应调用“最终”过程(如果指定)。但是对我来说,GNU没有调用“最终”程序,而intel却调用了。我必须显式取消分配我的allocatabale对象。
© www.soinside.com 2019 - 2024. All rights reserved.