Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Fortran子例程在多次迭代后忘记可分配的数组元素值_Fortran_Save_Allocatable Array - Fatal编程技术网

Fortran子例程在多次迭代后忘记可分配的数组元素值

Fortran子例程在多次迭代后忘记可分配的数组元素值,fortran,save,allocatable-array,Fortran,Save,Allocatable Array,我有一个fortran程序,其结构如下所示。这个程序由于“分段错误”而崩溃,所以我对根本原因进行了大量挖掘 结果是,在子程序SUB1中,当DO循环计数器变量I达到187606的值时,Z(608673)的值(最初从外部文件读取为28.29)不知怎的莫名其妙地变为3.9809702045652999E-309,即使没有计算会改变任何X的值,从外部文件读取后的Y或Z数组 我怀疑程序在执行过程中(可能在零左右)也会将许多其他数组元素值设置为任意数-尽管鉴于数组的大尺寸,无法明确检查是否存在这种情况-但本

我有一个fortran程序,其结构如下所示。这个程序由于“分段错误”而崩溃,所以我对根本原因进行了大量挖掘

结果是,在子程序SUB1中,当DO循环计数器变量I达到187606的值时,Z(608673)的值(最初从外部文件读取为28.29)不知怎的莫名其妙地变为3.9809702045652999E-309,即使没有计算会改变任何X的值,从外部文件读取后的Y或Z数组

我怀疑程序在执行过程中(可能在零左右)也会将许多其他数组元素值设置为任意数-尽管鉴于数组的大尺寸,无法明确检查是否存在这种情况-但本质上这是导致程序崩溃的原因(这些值在程序的其他地方使用)

因此,主要的问题是:尽管这些数组保存在模块变量中,并且所有相关例程都在使用这个模块,为什么程序会任意重置数组元素值?SAVE语句不是用来保存数组的值吗

注意:我尝试在[a]具有16 GB内存的Ubuntu Linux Dell笔记本电脑(没有运行其他内存不足的程序)和[b]具有16 GB内存的Windows笔记本电脑上运行此代码。在这两台机器上,我都使用了gfortran编译器,出现了相同的问题。对于较小的N值,代码似乎运行良好-只有非常大的阵列才是问题

文件vars.f90 文件分配.f90 文件deallocate.f90 文件main.f90 文件datafile.txt(小样本):
如果大数字溢出,则可能出现如下情况:

USE ISO_C_BINDING
INTEGER(KIND=C_Int32_t) :: N
或者,首先在中添加一些调试语句,以确保您传递的数字实际按预期接收

如果32位不够,那么C_Int64_t可以容纳更大的数字


使用ISO_C_绑定,实数(8)也可以是实数(KIND=C_DOUBLE),而ISO_C_绑定是定义大小的一种不错的方法。

如果大数字溢出,则可能类似以下情况:

USE ISO_C_BINDING
INTEGER(KIND=C_Int32_t) :: N
或者,首先在中添加一些调试语句,以确保您传递的数字实际按预期接收

如果32位不够,那么C_Int64_t可以容纳更大的数字


使用ISO_C_绑定时,实数(8)也可以是实数(KIND=C_DOUBLE),而ISO_C_绑定是定义大小的一种不错的方法。

我经常发现(旧的)的分段错误Fortran程序和大维度,因为总有一个堆栈分配数组在某处。使用
ulimit-s unlimited
避免堆栈大小限制在这种情况下(在Linux中)会有所帮助。另外,用Valgrind运行程序可能会指出一些问题。@jacob谢谢,但不幸的是,这并没有解决问题。我经常对(旧版)产生分段错误Fortran程序和大维度,因为总有一个堆栈分配数组在某处。使用
ulimit-s unlimited
避免堆栈大小限制在这种情况下(在Linux中)会有所帮助。另外,用Valgrind运行程序可能会指出一些问题。@jacob谢谢,但不幸的是,这并不能解决问题。谢谢。我尝试了两种方法,
C_Int32_t
C_Int64_t
,但遗憾的是,它们都没有解决问题。谢谢。我尝试了这两种方法,
C_Int32_t
C_Int64_t
,但遗憾的是,它们都没有解决问题。
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
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
.....
.....
10879.544935    1200.249974       28.290163
10914.193168     205.374638      236.847393
23872.837623    3634.498293    23721.923293
.....
.....
USE ISO_C_BINDING
INTEGER(KIND=C_Int32_t) :: N