Memory leak when assigning allocatable polymorphic variable with return value

若如初见. 提交于 2021-02-20 00:48:58

问题


I'm struggling with memory management or correct usage of object oriented Fortran 2008. My code has multiple derived types with the same parent (here Example01 and Example02) stored in a Example_Class module. I want to load one example in a subroutine workenv depending on some variable (here idx_example). Whichever one is chosen should be accessed by procedures defined in the base class, so I can do call active_Example%Info() regardless of what active_Example is.

The following code compiled with ifort (19.0.1.144) or gfortran (7.5.0) works as intended. But valgrind (3.13.0) warns about memory leakage (see below code). What can I do to prevent memory leakage and have the same or a similar functionality? (I would like to have the control in the Example_class module and not use multiple if-conditions in the workenv subroutine.)

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

When using ifort -free -stand f08 Examples.f -o Examples I can observe

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)

With 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)

来源:https://stackoverflow.com/questions/61098780/memory-leak-when-assigning-allocatable-polymorphic-variable-with-return-value

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