我对使用TYPE
和CLASS
在使用Fortran中的类型绑定过程定义链接列表时感到困惑。以下简单程序导致get_num_nodes
函数中的分段错误。但是,如果我将指针next
的声明从CLASS
更改为TYPE
,程序将正常结束。
当我使用ifort
(版本14.0.2)构建分段错误时,会发生分段错误。
如果我使用gfortran(版本4.8.4和7.2.0)构建它,CLASS
和TYPE
的两种情况都会正常结束。
在声明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
$