2012-02-07 15 views
7

Me gustaría utilizar listas vinculadas en Fortran para mantener una matriz de datos de una longitud indefinida.¿Cómo desasigna Fortran las listas vinculadas?

tengo la siguiente configuración:

TYPE linked_list 
    INTEGER :: data 
    TYPE(linked_list) :: next_item => NULL() 
END TYPE 

Ahora dicen que puedo crear una lista de este tipo:

TYPE(LINKED_LIST) :: example_list 
example_list%data =1 
ALLOCATE(example_list%next_item) 
example_list%next_item%data = 2 
ALLOCATE(example_list%next_item%next_item) 
example_list%next_item%next_item%data = 3 

Mi pregunta es, si realizo:

DEALLOCATE(example_list) 

hará todo el los niveles anidados también se desasignan o necesito atravesar la lista hasta el elemento más profundo y desasignar desde el elemento más profundo t hacia arriba?

+4

Ha sido un largo tiempo desde que hice esto en Fortran, pero estoy bastante seguro de que tiene que cancelar la asignación manualmente. Si desasigna la cabeza, perderá la referencia y tendrá una pérdida de memoria. – ChrisF

+0

Sí. Tenía mucho miedo de eso. Debo decir, sin embargo, estoy teniendo problemas, ¿cuál es la frase, rodando mi propia colección de basura? – EMiller

+0

No puede implementar Fortran administrado por memoria. –

Respuesta

9

Debe desasignar cada nodo manualmente. Aquí es donde el estilo "orientado a objetos" resulta útil.

module LinkedListModule 
    implicit none 
    private 

    public :: LinkedListType 
    public :: New, Delete 
    public :: Append 

    interface New 
     module procedure NewImpl 
    end interface 

    interface Delete 
     module procedure DeleteImpl 
    end interface 

    interface Append 
     module procedure AppendImpl 
    end interface 

    type LinkedListType 
     type(LinkedListEntryType), pointer :: first => null() 
    end type 

    type LinkedListEntryType 
     integer :: data 
     type(LinkedListEntryType), pointer :: next => null() 
    end type 

contains 

    subroutine NewImpl(self) 
     type(LinkedListType), intent(out) :: self 

     nullify(self%first) 
    end subroutine 

    subroutine DeleteImpl(self) 
     type(LinkedListType), intent(inout) :: self 

     if (.not. associated(self%first)) return 

     current => self%first 
     next => current%next 
     do 
      deallocate(current) 
      if (.not. associated(next)) exit 
      current => next 
      next => current%next 
     enddo 

    end subroutine 

    subroutine AppendImpl(self, value) 

     if (.not. associated(self%first)) then 
      allocate(self%first) 
      nullify(self%first%next) 
      self%first%value = value 
      return 
     endif 


     current => self%first 
     do 
      if (associated(current%next)) then 
       current => current%next 
      else 
      allocate(current%next) 
      current => current%next 
      nullify(current%next) 
      current%value = value 
      exit 
      endif 
     enddo 

    end subroutine 

end module 

Cuidado: es pasada la medianoche y no me gusta codificar en una ventana del navegador. Este código puede no funcionar. Es solo un diseño.

uso como esto

program foo 
    use LinkedListModule 
    type(LinkedListType) :: list 

    call New(list) 
    call Append(list, 3) 
    call Delete(list) 
end program 
+1

Bingo. El método DeleteImpl es exactamente lo que estaba buscando. Qué bonito y ordenado es este fortran orientado a objetos. – EMiller

+1

@emiller: No está orientado a objetos. Es un estilo orientado a objetos. –

+0

'Append' barre toda la lista, desde la cabeza hasta la cola, por lo que es muy ineficiente.Es mejor hacer un seguimiento del nodo de cola y agregarle el nuevo nodo. ¿Por qué se distingue 'LinkedListType' de' LinkedListEntryType'? –

Cuestiones relacionadas