On Sep 16, 2:40Â pm, Paul van Delst
noaa.gov> wrote:
> Richard Maine wrote:
>
>>> Dear all,
>>> Â Â is there a way to overload the operators +, =, ... for a derived
>>> type with pointer components which does not leak memory?
>
>>> To be more precise, the attached code, according to valgrind, leaks
>>> the memory allocated in tt_sum (which indeed seems reasonable to me).
>>> Is there a way to rearrange this code to avoid memory leaks?
>
>>> I have to add that 1) in general I can not switch to allocatable
>>> components 2) I think a FINAL procedure might solve the problem, but I
>>> wonder how many compilers support it.
>
>> Well, you've ruled out the easy one, namely to make it allocatable. It
>> really looks like pointer is being used as a surrogate for allocatable
>> here.
>
>> Other than that, you could test whether the component is associated
>> before allocating a new one. Deallocate any old one. But this requires
>> *LOTS* of care to get it all right. Two basic things.
>
> [snip basic things]
>
> Will being extra careful as you suggest still be enough?
>
> I did the following to the original code:
>
> module mm
> Â implicit none
> Â type tt
> Â Â real, pointer :: x(:) => NULL() Â ! ***change
> Â end type tt
> Â interface operator(+)
> Â Â module procedure tt_sum
> Â end interface
> Â interface assignment(=)
> Â Â module procedure tt_def
> Â end interface
> contains
> Â function tt_sum(x,y) result(z)
> Â Â type(tt), intent(in) :: x,y
> Â Â type(tt) :: z
> Â Â if (associated(z%%x)) deallocate(z%%x) Â ! ***change (correct?)
> Â Â allocate(z%%x(size(x%%x)))
> Â Â z%%x = x%%x + y%%x
> Â end function tt_sum
>
> Â subroutine tt_def(y,x)
>   type(tt), intent(in out) :: y  ! ***change
> Â Â type(tt), intent(in) :: x
> Â Â if (associated(y%%x)) deallocate(y%%x) Â ! ***change
> Â Â allocate(y%%x(size(x%%x)))
> Â Â y%%x = x%%x
> Â end subroutine tt_def
> end module mm
>
> program test
> Â use mm
> Â implicit none
> Â type(tt) :: a,b,c
> Â allocate(a%%x(5),b%%x(5))
> Â a%%x = (/ 1.0 , 2.0 , 3.0 , 4.0 , 5.0 /)
> Â b%%x = -2.0
> Â c = a+b
> Â deallocate(a%%x,b%%x,c%%x)
> end program test
>
> and I still get the memory leak in tt_sum. It seems to me that this example will always
> leak somewhere inbetween the "+" and the "=". (only tried one compiler)
>
> Is the assignment to z in tt_sum the same as the assignment to y in tt_def, and
> subsequently c in the main prog? One of these structures is getting lost (since valgrind
> reports a fixed loss of 20 bytes, i.e. one of the x(5)'s.)
>
> The line
> Â Â c=a+b
> first calls tt_sum to do the "a+b" bit. Then tt_def is called to do the "c=..." bit. But
> what(or where) is the rhs of the assignment? The z result of tt_sum becomes the x input of
> tt_def...but where does the x input of tt_def "go" after the assignment is done?
>
> Crikey, trying to explain what I think I mean is confusing me.
>
> cheers,
>
> paulv
Correct me if I am wrong but isnt 'z%%x' in tt_sum being lost here?
Also isnt this more like a compiler bug?