Утечка памяти при назначении выделяемой переменной polymorphi c с возвращаемым значением - PullRequest
1 голос
/ 08 апреля 2020

Я борюсь с управлением памятью или правильным использованием объектно-ориентированного Fortran 2008. В моем коде есть несколько производных типов с одним и тем же родителем (здесь Example01 и Example02), которые хранятся в модуле 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)
...