Fortran 取消分配导致程序停止而不显示错误消息

Fortran 取消分配导致程序停止而不显示错误消息,fortran,allocatable-array,Fortran,Allocatable Array,我正在通过Brian Hahn的《科学家和工程师用Fortran 90》一书学习Fortran。在第9章关于数组(第131/132页)中,他给出了以下代码作为动态数组的示例 Program Chap_9_Allocatable_Array Implicit none ! Variables Real, dimension(:), Allocatable :: X, OldX Real A Integer

我正在通过Brian Hahn的《科学家和工程师用Fortran 90》一书学习Fortran。在第9章关于数组(第131/132页)中,他给出了以下代码作为动态数组的示例

Program Chap_9_Allocatable_Array

Implicit none

! Variables
Real, dimension(:), Allocatable    :: X, OldX
Real                                  A
Integer                               IO, N, i

! Body of Chap_9_Allocatable_Array
Allocate( X(0) )                   !Size zero to sart with?
N = 0
Open(1, File = 'Data.txt')

Do
    Read(1, *, IOStat = IO) A
    If (IO < 0) Exit
    N = N + 1
    Allocate( OldX( Size(X) ) )
    OldX = X                       !Entire array can be assigned
    Deallocate( X )
    Allocate( X(N) )
    X = OldX
    X(N) = A
    Deallocate( OldX )
End do

Print *, (X(i), i = 1, N)

End program Chap_9_Allocatable_Array
程序Chap\u 9\u可分配\u数组
隐式无
! 变量
实型,维度(:),可分配::X,OldX
真正的
整数IO,N,i
! Chap_9_可分配_数组的主体
分配(X(0))!零号到沙尔特的尺寸?
N=0
打开(1,文件='Data.txt')
做
读取(1,*,IOStat=IO)A
如果(IO<0)退出
N=N+1
分配(OldX(大小(X)))
OldX=X!可以分配整个阵列
解除分配(X)
分配(X(N))
X=OldX
X(N)=A
解除分配(OldX)
结束
打印*,(X(i),i=1,N)
结束程序Chap_9_可分配_数组
我已在Visual Studio Community 2019中使用Intel Visual Fortran编译器实现了此程序。正如他所解释的,这个计划的目的是

下面的程序摘录展示了如何使用可分配数组来读取未知数量的数据,不幸的是,由于读取的工作方式,每行必须提供一项数据

我发现了一个有趣的错误。文件data.txt由100个随机数组成,每行1个。当我尝试运行它时,它似乎只是暂停了几秒钟,然后控制台简单地打印

按任意键继续

提示,但不显示错误消息。我插入了一些调试打印,并确定程序在停止之前运行3到8次do循环。我无法确定原因。如果我随后将data.txt文件更改为仅3个数字长,则程序将按预期运行。通过调试打印,我将错误锁定为

解除分配(X)

线路。如果我在Visual Studio中调试程序,我只会收到以下消息:

Chap_9_Allocatable_Array.exe已触发断点


这本书中有几个小错误。就在这个例子中,作者似乎忘记了声明i,这导致了编译错误。然而,由于我只是想了解数组,我不知道还有什么好尝试的。有什么想法吗?

X=OldX-这正是书中所说的吗?如果是这样的话,请仔细想想为什么它可能没有被纠正,这是一种从未知大小的文件中读取内容的糟糕方法。当循环退出时,您已经完成了2*N+1
ALLOCATE
s和2*N
DEALLOCATE
s。还可以将数据从一个数组复制到另一个数组。那是个糟糕的设计。根据编译器选项的不同,并考虑@IanBush的注释,您可能需要执行额外的N
ALLOCATE
s和
DEALLOCATE
s操作,并写入一个越界数组位置。最好是读取文件,只需计算一个do循环中的行数。然后倒带IO单元,分配
X(N)
一次,然后在第二个do-loop中重新读取文件。据我所知,他不是想优化书中的代码,而是想调试它。为此,@IanBush的评论应该是perfect@jack实际上,伊恩的评论并不完美
X=OldX
是有效的现代Fortran,在现代Fortran中,分配时会发生重新分配。有问题的语句是下一个:
X(N)=A
步出重新分配的
X
。他应该完全重写代码以避免不必要的分配和解除分配,或者将分配更改为
X(1:n-1)=OldX
X=[OldX,A]
@evets-噢,我很高兴单独的声明是正确的。然而,就程序逻辑而言,它仍然是错误的,重新分配在这里是不正确的——所以我的评论。但是OP似乎已经在自己解决问题上迈出了重要的一步,这是我的主要观点,因为这样做他们将学到比被告知答案更多的东西。