Silverfrost Forums

Welcome to our forums

Memory leaks by pointers to derived data types?

27 Sep 2022 5:37 #29391

Hi there,

currently I have a problem with leaking memory and I am at my wits end to track it down. The code is rather long, so no sense in posting it here, but I try to describe how my program works.

My variables are of derived type, a mixture of integers and reals, no matrices or arrays. They are organised in a linked list. The type definition of variables and pointers are done in a module, each procedure to access the data has a use-statement to this module

In a loop new data are generated which are sorted into the linked list and some data are destroyed. The list typically holds bout 3,000 to 4,000 items with about 40 to be added and removed each time my main loop is processed.

For debugging I have a count of allocations and deallocations running which shows a balance exact as it should be, namely the number of the active items as open allocations.

Some procedures to manipulate the data use their local set of pointers which get nullified manually when the precedure terminates.

But still I have an increase of memory as monitored with Task Manager from about 28 MB at startup to 76 MB after 3,000 cycles, while the memory consumption is about 36 MB when my linked list is fully loaded.

So what can I do? Is there a useful strategy to track down this memory leak? Are there tools around to check for memory leaks? Should I use another approach?

I am using Plato and FTN95 version 8.80, compiling /64 and running in a windows 11 environment. I use clearwin+ with format windows with /og graphic.

Any idea?

27 Sep 2022 9:10 #29392

Try using /debug and stepping through the code using the debugger, watching the memory increase via the Task manager as you step through.

If you are happy with your own direct memory usage, look out for changes when entering and leaving ClearWin+ code.

28 Sep 2022 1:49 #29393

Quoted from ursuselasticus Some procedures to manipulate the data use their local set of pointers which get nullified manually when the precedure terminates.

If the pointers are associated with allocated memory, this memory must be deallocated. I think that to only nullify would leak the memory. Nullify or redirecting pointers will loose the address of the previous allocated memory and so then be leaked.

Also with allocated components of derived types, these must be specifically deallocated, reversing through the derived type structure.

( this is a great approach for flexible data structures, but be careful with small allocated components as there is a memory overhead with tracking the size of these allocatable components. )

What compile option are you using, as /check did at one time leak memory on deallocate. Not sure if it still does. You are using /check, try /debug and see if that changes the memory status.

28 Sep 2022 3:16 #29394

I've been using:

if(associated(item)) deallocate(item)

This prevents an error if you deallocate something that hasn't actually been allocated. However, it obfuscates deallocation of memory when you didn't allocate it first.

I don't use NULLIFY for an actual allocation. I will use it if I am passing a pointer to memory in a callback routine that allocates using that pointer. JIC.

Just a thought. Bill

28 Sep 2022 6:16 #29396

John

I am not aware of any memory leak problems with /check.

32 bit FTN95 with /check allocates memory in a special way, allocating large chunks at a time and then micro-managing the user allocation. But even there I am not aware of any outstanding issues.

28 Sep 2022 10:43 #29397

Thanks for your response.

I was able to pinpoint the source of my memory leak - but I am at a loss on how to solve it. The following code is the essence of my approach - and highlights in fact two problems:

program MemoryTest

    type mytype
        real rA (100,100)
        integer iB (100,100)
    endtype
    	
    type (mytype) tC
    type (mytype), pointer :: pC, pD
 
    tC%rA = 2.0
    tC%iB = 3

    do j = 1, 100000
        allocate (pC, stat = iStat)
        if (iStat .ne. 0) then
            print*, 'Allocate went wrong, iStat = ', iStat
            stop
        endif

        pC = tC
        pD => pC

        deallocate (pC, stat = iStat)
        if (iStat .ne. 0) then
            print*, 'Deallocate went wrong, iStat = ', iStat
            stop
        endif

        if (associated (pD)) print*, j
    enddo
end program

First: It produces a considerable memory leak. It does not help to nullify pD prior to deallocating pC. The memory loss remains the same. And Second: The 'if associated' statement fails to recognize that the pointer pD is not associated any more due the pointer it pointed to being deallocated. Program compiled by FTN95 v. 8.80, \64, Windows 11. Cheers Norbert

28 Sep 2022 10:58 #29398

Still messing around with this little program. Here is the ultimate essence to produce this memory leak.

program MemoryTest

type mytype
  real rA (100,100)
  integer iB (100,100)
endtype
    	
type (mytype), pointer :: pC

do j = 1, 100000
      	
  allocate (pC, stat = iStat)
  deallocate (pC, stat = iStat)
  print*, j       ! slow down execution a bit

enddo
end program
28 Sep 2022 12:47 #29399

There will appear to be a memory leak when using /CHECK (or any option that implies /CHECK) because (up to a certain limit of total memory used) memory is not actually released to the system. This is to allow checking for dangling pointers.

In order to avoid this part of the checking mechanism, use /INHIBIT_CHECK 4 or in some situations /INHIBIT_CHECK 3.

After testing and debugging it is normal to switch off /CHECK etc.

Sorry I did not think of this earlier.

28 Sep 2022 1:48 #29400

Thanks a lot.

Problem solved.

Cheers Norbert

Please login to reply.