我有一个具有以下结构的 fortran 程序。该程序因“分段错误”错误而崩溃,因此我对根本原因进行了很多挖掘。
原来,在子程序 SUB1 中,当 DO 循环计数器变量 I 达到 187606 的值时,原来从外部文件中读取为 28.29 的 Z(608673) 的值莫名其妙地变成了 3.9809702045652999E-309,即使在从外部文件读取后没有任何计算会改变任何 X、Y 或 Z 数组的值。
我怀疑许多其他数组元素值也被程序在执行中途设置为任意数字(可能在零附近) - 尽管鉴于数组的大尺寸不可能明确检查这一点 - 但本质上这是是什么导致程序崩溃(这些值在程序的其他地方使用)。
所以主要的问题是:为什么数组元素值被程序任意重置,尽管这些数组保存在 MODULE VARIABLES 中并且该模块被所有相关例程使用?SAVE 语句不是用来保存数组的值吗?
注意:我尝试在 [a] 具有 16 GB RAM 的 Ubuntu Linux Dell 笔记本电脑(没有运行其他需要大量内存的程序)和 [b] 具有 16 GB RAM 的 Windows 笔记本电脑上运行此代码。在这两台机器上,我都使用了 gfortran 编译器,并且出现了同样的问题。对于较小的 N 值,代码似乎运行良好 - 只有非常大的数组是一个问题。
文件 vars.f90
MODULE VARIABLES
......
......
INTEGER :: N
REAL(8), DIMENSION(:), ALLOCATABLE :: X,Y,Z
SAVE N
SAVE X,Y,Z
.....
.....
... (several other variable declarations) ....
END MODULE VARIABLES
文件分配.f90
MODULE ALLOCATE_ARRAYS
CONTAINS
SUBROUTINE ALLOC_ARR
USE VARIABLES
USE DEALLOCATE_ARRAYS
.....
ALLOCATE(X(N),Y(N),Z(N), STAT=IALLOC)
IF (IALLOC /= 0) THEN
WRITE(6,*)' ERROR while allocating arrays X Y Z'
CALL DEALLOC_ARRAYS
STOP
ENDIF
.....
END SUBROUTINE ALLOC_ARR
END MODULE ALLOCATE_ARRAYS
文件解除分配.f90
MODULE DEALLOCATE_ARRAYS
CONTAINS
SUBROUTINE DEALLOC_ARR
USE VARIABLES
.....
IF (ALLOCATED(X)) DEALLOCATE(X)
IF (ALLOCATED(Y)) DEALLOCATE(Y)
IF (ALLOCATED(X)) DEALLOCATE(X)
...
END SUBROUTINE DEALLOC_ARR
END MODULE DEALLOCATE_ARRAYS
文件 main.f90
PROGRAM PROG1
USE VARIABLES
USE ALLOCATE_ARRAYS
USE DEALLOCATE_ARRAYS
.....
N = 18666800 ![in practice this is read from an external input file]
CALL ALLOC_ARR !Allocate X,Y,Z each to be of length N
!Read all values of X(1:N), Y(1:N) and Z(1:N) from an external file] ...
OPEN(11,FILE=datafile.txt,STATUS='OLD')
DO I = 1,N
READ(11,*,IOSTAT=ISTAT) X,Y,Z
IF ( ISTAT /= 0 ) THEN
WRITE(6,*)' *** SERIOUS WARNING ***'
WRITE(6,*)' Something went wrong while trying to read numbers X Y Z at I = ',I
READ(5,*)
ENDIF
ENDDO
CLOSE(11)
CALL SUB1
.....
CALL DEALLOC_ARRAYS
END PROGRAM PROG1
SUBROUTINE SUB1
USE VARIABLES
USE ALLOCATE_ARRAYS
USE DEALLOCATE_ARRAYS
.....
DO I = 1,N
write(6,*)' X(608673) Y(608673) Z(608673) = ',X(608673),Y(608673),Z(608673) ![this statement only inserted for tracing the bug]
CALL SUB2(I,X(I),Y(I),Z(I))
ENDDO
END SUBROUTINE SUB1
SUBROUTINE SUB2(IPASS,XPASS,YPASS,ZPASS)
USE VARIABLES
USE ALLOCATE_ARRAYS
USE DEALLOCATE_ARRAYS
[carry out some calculations that use the values of IPASS, XPASS, YPASS, ZPASS, but never change their values]
END SUBROUTINE SUB2
文件 datafile.txt(小样本):
.....
.....
10879.544935 1200.249974 28.290163
10914.193168 205.374638 236.847393
23872.837623 3634.498293 23721.923293
.....
.....