2012-02-07 34 views
7

Tôi muốn sử dụng danh sách được liên kết trong Fortran để giữ một mảng dữ liệu có độ dài không xác định.Fortran deallocate danh sách liên kết như thế nào?

tôi có các thiết lập sau:

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

Bây giờ nói tôi tạo ra một danh sách như vậy:

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 

Câu hỏi của tôi là, nếu tôi thực hiện:

DEALLOCATE(example_list) 

sẽ tất cả các mức lồng nhau cũng được deallocated hoặc tôi cần phải đi qua danh sách để các yếu tố sâu sắc nhất và deallocate từ elemen sâu nhất t lên?

+4

Nó được một thời gian dài kể từ khi tôi đã làm điều này trong Fortran, nhưng tôi khá chắc chắn bạn phải deallocate bằng tay. Nếu bạn chỉ cần deallocate đầu, sau đó bạn sẽ mất các tài liệu tham khảo và có một rò rỉ bộ nhớ. – ChrisF

+0

Có. Tôi khá sợ điều đó. Tôi phải nói mặc dù, tôi đang gặp rắc rối, cụm từ đó là gì, lăn bộ sưu tập rác của riêng tôi? – EMiller

+0

Bạn không thể triển khai bộ nhớ fortran được quản lý. –

Trả lời

9

Bạn phải deallocate mỗi nút theo cách thủ công. Đây là nơi "hướng đối tượng" như phong cách có ích.

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 

Hãy coi chừng: quá nửa đêm và tôi không thực sự thích viết mã trong cửa sổ trình duyệt. Mã này có thể không hoạt động. Nó chỉ là một cách bố trí.

Sử dụng như thế này

program foo 
    use LinkedListModule 
    type(LinkedListType) :: list 

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

Bingo. Phương pháp DeleteImpl chính xác là những gì tôi đang tìm kiếm. Làm thế nào tốt đẹp và gọn gàng đối tượng này hướng fortran là. – EMiller

+1

@emiller: Nó không hướng đối tượng. Đó là phong cách hướng đối tượng. –

+0

'Nối' quét qua toàn bộ danh sách, từ đầu đến đuôi, vì vậy nó rất không hiệu quả.Nó là tốt hơn để theo dõi các nút đuôi và để nối thêm nút mới vào nó. Tại sao phân biệt 'LinkedListType' từ' LinkedListEntryType'? –

Các vấn đề liên quan