【发布时间】:2020-08-29 23:03:34
【问题描述】:
我正在尝试使用链表进行选择排序。但是,我收到了分段错误。
"""
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
\#0 0x7f191e86a32a
\#1 0x7f191e869503
\#2 0x7f191e49cf1f
\#3 0x7f191e9e9330
\#4 0x7f191e9ed0b4
\#5 0x7f191e9e423c
\#6 0x7f191e9e46dc
\#7 0x55ed5c77be79
\#8 0x55ed5c77bfa6
\#9 0x7f191e47fb96
\#10 0x55ed5c77b9c9
\#11 0xffffffffffffffff
Segmentation fault (core dumped)
"""
我确信这是我尝试在“输出”do 循环之间写出数据时造成的。我发现很难看出我是如何搞砸记忆的。
非常感谢任何帮助!非常感谢您!
program insertion_sort
implicit none
! Derived data type to store integer values in
type int_value
integer :: value
type (int_value), pointer :: next_value
end type
! Data dictionary: declare variable types & definitions
type (int_value), pointer :: head ! Pointer to head of list
character(20) :: filename ! input data file name
integer :: istat ! status: 0 for succes
integer :: nvals = 0 ! Number of data read
type (int_value), pointer :: ptr ! Ptr to new value
type (int_value), pointer :: ptr1 ! Temp ptr for search
type (int_value), pointer :: ptr2 ! Temp ptr for search
type (int_value), pointer :: tail ! Pointer to tail of list
integer :: temp ! Temporary variable
! Get the name of the file containing the input data
write (*,*) 'Enter the file name with the data to be sorted'
read (*,'(A20)') filename
! Open input data file
Open (Unit=9, file=filename, status='OLD', action='read', &
iostat=istat )
! Was the open succesful
fileopen: if ( istat == 0 ) then ! Open succesful
! The file was opened succesfully, so read the data value
! to sort, allocate a variable for it, and locate the proper
! point to insert the new value into the list
input: do
read (9, *, iostat=istat) temp ! Get value
if ( istat /=0 ) exit ! Exit on end of data
nvals = nvals + 1 ! Bump count
allocate (ptr, STAT=istat) ! Get value
ptr%value = temp ! Store number
! Now find out where to put it in the list.
new: if (.not. associated(head)) then ! No values in list
head => ptr ! Place at front
tail => head ! Tail pts to new value
nullify (ptr%next_value) ! nullify next ptr
else
! Values alreadd in list. Check for location.
front: if ( ptr%value < head%value ) then
! Add at front of list
ptr%next_value => head
head => ptr
else if ( ptr%value >= tail%value ) then
! Add at end of list
tail%next_value => ptr
tail => ptr
nullify (tail%next_value)
else
! Find place to add value
ptr1 => head
ptr2 => ptr1%next_value
search: do
if ( (ptr%value >= ptr1%value) .and. &
(ptr%value < ptr2%value) ) then
! Insert value here
ptr%next_value => ptr2
ptr1%next_value = ptr
exit search
end if
ptr1 => ptr2
ptr2 => ptr2%next_value
end do search
end if front
end if new
end do input
! WHERE I BELIEVE THE SEGMENTATION FAULT OCCURS
! Now write out the data.
ptr => head
output: do
if ( .not. associated(ptr) ) exit ! Pointer valid?
write (*, '(I10)') ptr%value ! Yes: Write value
ptr => ptr%next_value ! Get next pointer
deallocate(ptr, StAT=istat)
end do output
else fileopen
! Else file open failed. Tell user.
write (*, '(A,I6)') 'File open failed--status =', istat
end if fileopen
end program insertion_sort
【问题讨论】:
-
请使用 -g 重新编译以获取调试信息,以便显示更合理的回溯。
-
当你遇到这些问题时,使用你的编译器有的所有调试标志。例如
gfortran -g -Wall -fcheck=all或ifort -g -warn -check。众所周知,这些带有指针的代码很难推理,调试通常必须使用调试器和类似工具(例如 valgrind)来完成。不能只看回溯就看到错误。 -
为什么在完成指针分配后释放
PTR?也就是说,ptr => ptr%next_value ; deallocate(ptr, StAT=istat)不可能是你想做的。 -
Fortran 中的指针可以是关联的、未关联的或未定义的。您不能将
ASSOCIATED与未定义的指针一起使用。head变量的初始状态是什么? -
这一行也不能满足你的要求
ptr1%next_value = ptr。普通赋值和指针赋值是有区别的。
标签: linked-list segmentation-fault fortran selection-sort