Still more linked list magic :-)



!Hello,

!I'm back again (-: no more bugs this time (thanks to your help),
!but I have a puzzling question on the way pointers work. As
!suggested by highegg, I write a complete working code (you can
!even cut and paste the complete post and compile it). The
!program is similar to the one Jugoslav wrote in post
!4hf5bbF1qde3vU1@xxxxxxxxxxxxxx, thread "Cannot deallocate a
!linked list". There are, however, some small but important
!differences.

MODULE linked_list


IMPLICIT NONE


SAVE


! Derived data types
TYPE :: my_pointer
REAL :: component ! data
TYPE(my_pointer), POINTER :: next => NULL() ! pointer to next
element
END TYPE my_pointer


! Module variables
TYPE(my_pointer), POINTER :: head, tail !head=>null(), tail=>null()
CONTAINS


SUBROUTINE dealloc_list(error) ! here it is the bad guy


IMPLICIT NONE


!calling parameters
INTEGER, INTENT(OUT) :: error ! 0 if deallocation succeeded
!local variables
INTEGER :: istat ! 0 if pointer deallocation succeeded
TYPE(my_pointer), POINTER :: current ! pointer to actual element
TYPE(my_pointer), POINTER :: temp ! used to keep track of the element
! following current before deallocating it


error = 0
! Check if the head of the list is allocated, otherwise exit
IF ( .NOT. ASSOCIATED(head) ) RETURN


current => head
DO
IF ( .NOT. ASSOCIATED(current) ) EXIT ! End of list reached


IF (ASSOCIATED(current%next)) THEN
temp => current%next
DEALLOCATE(current, STAT=istat)
IF ( istat /= 0 ) THEN
error = 1
RETURN
END IF
current => temp ! Proceed to next point
ELSE
DEALLOCATE(current, STAT=istat)
IF ( istat /= 0 ) THEN
error = 1
RETURN
END IF
END IF
END DO
!! FIRST DIFFERENCE
PRINT *, 'in dealloc_list, before explicit nullification of head:'
PRINT *, 'status of head'
PRINT *, ASSOCIATED(head)
PRINT *, 'status of head%next'
PRINT *, ASSOCIATED(head%next)
PRINT *, 'status of head%next%next'
PRINT *, ASSOCIATED(head%next%next)
!!
NULLIFY(head)


END SUBROUTINE dealloc_list


END MODULE linked_list




! LinkList.f90
!
! FUNCTIONS:
! LinkList - Entry point of console application.
!


!**************************************************************************­**

!
! PROGRAM: LinkList
!
! PURPOSE: Entry point for the console application.
!
!**************************************************************************­**



program LinkList


use linked_list


implicit none


integer:: i, j
TYPE(my_pointer), POINTER :: current ! pointer to actual element


! Variables
allocate(head)
current => head
current%component = 0


do i=1,10
allocate(current%next)
current%next%component = i
current=>current%next
end do

!! SECOND DIFFERENCE
print *, 'before calling dealloc_list:'
print *, 'status of head'
print *, associated(head)
!!
call dealloc_list(i)


print *, 'after calling dealloc_list:'
print *, 'status of head'
print *, associated(head)


! Body of LinkList


end program LinkList


!Now, if I compile and execute this code, the output is:

!before calling dealloc_list:
!status of head
!T
!in dealloc_list, before explicit nullification of head:
!status of head
!T
!status of head%next
!T
!status of head%next%next
!T
!after calling dealloc_list:
!status of head
!F

!That doesn't sound right to me. I agree that "head" should
!be still associated, *in* dealloc_list but *before* explicit
!nullification. But why "head"'s followers are also still
!associated? We deallocated them before. However, the thing
!that I really cannot understand is this: try commenting out
!the second difference, i.e. instructions

! print *, 'before calling dealloc_list:'
! print *, 'status of head'
! print *, associated(head)

!in program LinkList. Well, guess what happens now??

!Greetings,

!deltaquattro

.



Relevant Pages