Fortran中链接列表中指针的类型或类

时间:2017-09-10 22:04:56

标签: pointers linked-list fortran polymorphism intel-fortran

我对使用TYPECLASS在使用Fortran中的类型绑定过程定义链接列表时感到困惑。以下简单程序导致get_num_nodes函数中的分段错误。但是,如果我将指针next的声明从CLASS更改为TYPE,程序将正常结束。

当我使用ifort(版本14.0.2)构建分段错误时,会发生分段错误。 如果我使用gfortran(版本4.8.4和7.2.0)构建它,CLASSTYPE的两种情况都会正常结束。

在声明CLASS指针时使用next有什么问题?我怎么能理解这个问题?或者,代码的不同部分出了什么问题?

tll.f90

MODULE tll
  IMPLICIT NONE
  PRIVATE

  PUBLIC LLnode, add_node_at_head

  TYPE LLnode
     PRIVATE
     INTEGER                                  :: idx
     !TYPE(LLnode),                   POINTER :: next => null()
     ! .. using this declaration with TYPE works.
     CLASS(LLnode),                   POINTER :: next => null()
     ! .. this declaration with CLASS causes segmentation fault with 
     ! ifort. 
   CONTAINS
     PROCEDURE :: get_num_nodes
  END type LLnode

! ================================================================
CONTAINS
! ================================================================

  ! ****************************************************************
  SUBROUTINE add_node_at_head(p_head, idx_arg)
  ! ****************************************************************
    TYPE(LLnode),     POINTER, INTENT(INOUT) :: p_head
    INTEGER,                   INTENT(IN)    :: idx_arg
    !
    TYPE(LLnode),  POINTER :: p_new_head

    write(*,*) 'entered add_node_at_head..'

    allocate(p_new_head)
    p_new_head%idx = idx_arg
    p_new_head%next => p_head
    p_head => p_new_head

    write(*,*) '.. leaving add_node_at_head'

  END SUBROUTINE add_node_at_head



  ! ****************************************************************
  FUNCTION get_num_nodes(self) RESULT(num_nodes)
  ! ****************************************************************
    INTEGER                            :: num_nodes
    CLASS(LLnode), TARGET, INTENT(IN)  :: self
    !
    CLASS(LLnode), POINTER     :: p_node

    write(*,*) 'entered get_num_nodes ..'

    num_nodes = 0
    p_node => self
    do while (associated(p_node)) 
       num_nodes = num_nodes+1
       p_node => p_node%next
    end do

    write(*,*) '.. leaving get_num_nodes'

  END FUNCTION get_num_nodes


END MODULE tll

main.f90

PROGRAM main
  USE tll, ONLY : LLnode, add_node_at_head
  IMPLICIT NONE

  TYPE(LLnode),  POINTER  :: p_head=>null()
  INTEGER                 :: num_nodes

  call add_node_at_head(p_head, 10)
  num_nodes= p_head%get_num_nodes() 
  write(*,*) 'num_nodes=', num_nodes

  write(*,*) 'Normal End.'

END PROGRAM main

编译和执行:

$ ifort -c tll.f90
$ ifort -c main.f90
$ ifort -o exe main.o tll.o
$ ./exe 
 entered add_node_at_head..
 .. leaving add_node_at_head
 entered get_num_nodes ..
forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image              PC                Routine            Line        Source             
exe                000000000046DF09  Unknown               Unknown  Unknown
exe                000000000046C7DE  Unknown               Unknown  Unknown
exe                000000000043E3B2  Unknown               Unknown  Unknown
exe                0000000000422FC3  Unknown               Unknown  Unknown
exe                0000000000402A3B  Unknown               Unknown  Unknown
libpthread.so.0    00002B8FDBB48330  Unknown               Unknown  Unknown
exe                00000000004026D2  Unknown               Unknown  Unknown
exe                0000000000402402  Unknown               Unknown  Unknown
exe                0000000000402336  Unknown               Unknown  Unknown
libc.so.6          00002B8FDBD77F45  Unknown               Unknown  Unknown
exe                0000000000402229  Unknown               Unknown  Unknown
$ 

0 个答案:

没有答案