Freeing memory 
Author Message
 Freeing memory

I've written a small example of a linked-list. This works fine as a
linked list but according to valgrind (linux) there is a memory leak.
Given that I only have a handle on the start of the list what is the
best was to properly deallocate memory?

Thanks,

Simon Geard

program example7

  type l_entry
     integer :: value = -1
     type(l_entry), pointer :: next
  end type l_entry

  type(l_entry), pointer :: first, current
  integer                :: i

  ! Fill the list with odd numbers 1...9
  allocate(current)
  first => current
  do i=1,9,2
     current = l_entry(i,null())
     allocate(current%next)
     current => current%next
  end do

  ! Step thought the list outputting as we go
  current => first
  do
     if (.not. associated(current%next)) exit
     print *,current%value
     current => current%next
  end do
  deallocate(first)
end program example7

valgrind summary:
==16147==
==16147== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 19 from
2)
==16147== malloc/free: in use at exit: 40 bytes in 5 blocks.
==16147== malloc/free: 13 allocs, 8 frees, 5318 bytes allocated.
==16147== For counts of detected errors, rerun with: -v
==16147== searching for pointers to 5 not-freed blocks.
==16147== checked 118792 bytes.
==16147==
==16147== LEAK SUMMARY:
==16147==    definitely lost: 32 bytes in 4 blocks.
==16147==      possibly lost: 0 bytes in 0 blocks.
==16147==    still reachable: 8 bytes in 1 blocks.
==16147==         suppressed: 0 bytes in 0 blocks.



Wed, 23 Jul 2008 22:02:38 GMT  
 Freeing memory

Quote:
>  Given that I only have a handle on the start of
>  the list what is the  best was to properly
> deallocate memory?

Assuming the lists are not circular, you could write a
recursive routine that deallocates the list.  Call the
routine with successive "next" elements until "next"
is not ASSOCIATED, and then DEALLOCATE the
elements in the list upon the return.

You could also write a loop that iterates through the
list, freeing the elements of the list as it goes along.
The loop will require an extra variable to hold the
"next" value.

If the lists can be circular, the problem is much harder.

Bob Corbett



Wed, 23 Jul 2008 22:13:02 GMT  
 Freeing memory

Quote:
> program example7
>   type l_entry
>      integer :: value = -1
>      type(l_entry), pointer :: next
>   end type l_entry
>   type(l_entry), pointer :: first, current
>   integer                :: i
>   ! Fill the list with odd numbers 1...9
>   allocate(current)
>   first => current
>   do i=1,9,2
>      current = l_entry(i,null())
>      allocate(current%next)
>      current => current%next
>   end do
>   ! Step thought the list outputting as we go
>   current => first
>   do
>      if (.not. associated(current%next)) exit
>      print *,current%value
>      current => current%next
>   end do
>   deallocate(first)
> end program example7

Robert Corbett's answer is a good one, but have you noticed
that there are other errors in your code?  current%next does
not have a default initializer to NULL() nor is it explicitly
nullified in your loop, so the last pointer in your linked
list has undefined association status, and you most
definitely don't want that.  Also the last node in your
linked list is unused.  Though this seems intentional, I take
time here to disagree with your intent.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end



Thu, 24 Jul 2008 01:59:34 GMT  
 Freeing memory
Thanks. I've got a version with the type in a module and a recursive
delete as you suggest:
  recursive subroutine delete(current)
    type(l_entry), pointer :: current

    if (associated(current%next)) then
       call delete(current%next)
    end if
    deallocate(current)
  end subroutine delete



Thu, 24 Jul 2008 02:39:00 GMT  
 Freeing memory
I suppose I was hoping that someone would say that the memory would get
harvested once the linked-list went out of scope - seems not to be the
case though.
Well spotted on the null(). As for the unused last node it wasn't my
particular intent - I'm just writing a simple linked-list example.
Surely there will always be an unused last node otherwise current will
point to null()?


Thu, 24 Jul 2008 02:39:25 GMT  
 Freeing memory


Quote:
> I suppose I was hoping that someone would say that the memory would get
> harvested once the linked-list went out of scope - seems not to be the
> case though.
> Well spotted on the null(). As for the unused last node it wasn't my
> particular intent - I'm just writing a simple linked-list example.
> Surely there will always be an unused last node otherwise current will
> point to null()?

How then do you have an empty list?

--
Qolin

Email: my qname at domain
Domain: qomputing dot demon dot co dot uk



Fri, 25 Jul 2008 05:11:43 GMT  
 Freeing memory

Quote:

>>  Given that I only have a handle on the start of
>>  the list what is the  best was to properly
>> deallocate memory?

>Assuming the lists are not circular, you could write a
>recursive routine that deallocates the list.  Call the
>routine with successive "next" elements until "next"
>is not ASSOCIATED, and then DEALLOCATE the
>elements in the list upon the return.

>You could also write a loop that iterates through the
>list, freeing the elements of the list as it goes along.
>The loop will require an extra variable to hold the
>"next" value.

>If the lists can be circular, the problem is much harder.

It's no more difficult.
In this case, the "end" of the list occurs when
the last node and the head are pointing at the same node.


Fri, 25 Jul 2008 23:44:13 GMT  
 Freeing memory
...

Quote:
>> If the lists can be circular, the problem is much harder.

> It's no more difficult.
> In this case, the "end" of the list occurs when
> the last node and the head are pointing at the same node.

No, the end of the list is where the current node points
to any node between the head of the list and the current
node inclusive.  Lists that *can* be circular are often
circular to some lesser degree than totality.  Freeing such
lists requires marking nodes that you've visited so you
don't bother trying to free them twice, and you only
actually free the nodes after you've identified the
topology of the list (otherwise, the previously visited
nodes - including the mark indicating whether you've
visited them or not - are in an undefined state).  Processing
possibly circular lists in any way at all, including freeing
them, *is* harder than processing lists that are never
circular.

--
J. Giles

"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies."   --  C. A. R. Hoare



Sat, 26 Jul 2008 04:13:52 GMT  
 
 [ 8 post ] 

 Relevant Pages 

1. Problems freeing memory with Free

2. How to free memory?

3. Anyone know of a FREE() memory leak?

4. Free memory & DOS Extender

5. How to free memory ?

6. Free memory of waveform graph

7. Howto Free memory in CIN

8. access / freeing memory

9. EXPLANATION OF DOS INTERRUPT(21h) Function 49h (Free memory)

10. % Free Memory

11. How To Free Memory (Linked List)?

12. Free memory leak detection tool

 

 
Powered by phpBB® Forum Software