[Bug fortran/106750] New: Memory leak calling section of derived type containing `allocatable` entries
federico.perini at gmail dot com
gcc-bugzilla@gcc.gnu.org
Fri Aug 26 09:37:48 GMT 2022
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106750
Bug ID: 106750
Summary: Memory leak calling section of derived type containing
`allocatable` entries
Product: gcc
Version: 9.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: fortran
Assignee: unassigned at gcc dot gnu.org
Reporter: federico.perini at gmail dot com
Target Milestone: ---
Running a large CFD program I've found a memory leak gfortran 9.2.0 (sorry:
unable to test other versions on that system) that occurs when:
- derived type contains `allocatable` entries
- a chunk of an array of the aforementioned derived type is used as input to a
function
- happens whether or not the derived type contains a final routine
Here's a minimal working example:
module tmod
implicit none
type, public :: t
integer :: i,j,k
integer, allocatable :: a(:) ! No leaks if these are fixed-size
integer, allocatable :: b(:) ! No leaks if these are fixed-size
! integer :: a(3),b(20) ! uncomment to test fixed-size
end type t
contains
integer function do_with_array(ts) result(l)
type(t), intent(in) :: ts(2)
integer :: i(2),j(2),k(2)
i = max(ts(:)%i,0)
j = max(ts(:)%j,0)
k = max(ts(:)%k,0)
l = sum(i+j+k)
end function
integer function do_with_scalars(t1,t2) result(l)
type(t), intent(in) :: t1,t2
integer :: i(2),j(2),k(2)
i(1) = max(t1%i,0); i(2) = max(t2%i,0)
j(1) = max(t1%j,0); j(2) = max(t2%j,0)
k(1) = max(t1%k,0); k(2) = max(t2%k,0)
l = sum(i+j+k)
end function
end module tmod
program test
use tmod
implicit none
integer, parameter :: n = 1000
type(t), allocatable :: ts(:)
integer :: j(n),choose(2),i,k(n)
real :: x(2)
! Initialize with anything
allocate(ts(n));
do i=1,n
ts(i) = t(i,2*i,3*i,[(i,i=1,3)],[(2*i,i=1,20)])
end do
! Do several calls
do i=1,n
call random_number(x); choose = ceiling(x*n)
! [leak #1]
j(i) = do_with_array(ts(choose)) ! [#1] MEMORY LEAK
! no leak ever
k(i) = do_with_scalars(ts(choose(1)),ts(choose(2)))
end do
print *, 'sum=',sum(j)
! [leak #2] happens if ts is not deallocated. Shouldn't a program work like
a
! subroutine, and deallocate everything that's going out of scope?
deallocate(ts)
end program test
The results with valgrind are:
[perini1@srv0 ~]$ valgrind --tool=memcheck --leak-check=yes --track-origins=yes
./a.out
==49159== Memcheck, a memory error detector
==49159== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==49159== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==49159== Command: ./a.out
==49159==
sum= 5960916
==49159==
==49159== HEAP SUMMARY:
==49159== in use at exit: 197,026 bytes in 4,001 blocks
==49159== total heap usage: 6,023 allocs, 2,022 frees, 446,610 bytes
allocated
==49159==
==49159== 24,000 bytes in 2,000 blocks are definitely lost in loss record 2 of
3
==49159== at 0x4C28A2E: malloc (vg_replace_malloc.c:270)
==49159== by 0x402204: MAIN__ (test_leak.f90:55)
==49159== by 0x4026C9: main (test_leak.f90:36)
==49159==
==49159== 160,000 bytes in 2,000 blocks are definitely lost in loss record 3 of
3
==49159== at 0x4C28A2E: malloc (vg_replace_malloc.c:270)
==49159== by 0x402337: MAIN__ (test_leak.f90:55)
==49159== by 0x4026C9: main (test_leak.f90:36)
==49159==
==49159== LEAK SUMMARY:
==49159== definitely lost: 184,000 bytes in 4,000 blocks
==49159== indirectly lost: 0 bytes in 0 blocks
==49159== possibly lost: 0 bytes in 0 blocks
==49159== still reachable: 13,026 bytes in 1 blocks
==49159== suppressed: 0 bytes in 0 blocks
==49159== Reachable blocks (those to which a pointer was found) are not shown.
==49159== To see them, rerun with: --leak-check=full --show-reachable=yes
==49159==
==49159== For counts of detected and suppressed errors, rerun with: -v
==49159== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 8 from 6)
Profiling timer expired
More information about the Gcc-bugs
mailing list