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
Arrays Fortran子例程返回时失败_Arrays_Fortran_Fortran90 - Fatal编程技术网

Arrays Fortran子例程返回时失败

Arrays Fortran子例程返回时失败,arrays,fortran,fortran90,Arrays,Fortran,Fortran90,我有一个Fortran数字代码,可以从外部模块调用子程序。在我尝试在另一台机器上编译和运行之前,这段代码一直运行良好。在新机器上,我的程序崩溃得相当快 通过使用debug print语句,我发现崩溃发生在从外部子例程返回时。主程序多次调用子例程,在第二次调用子例程返回时发生崩溃(第一次调用工作正常)。它总是在使用这组输入数据的第二个子例程调用时崩溃,但在使用另一组输入数据(大约是第一组的1/3)时,它在从第五个子例程调用返回时崩溃 这些症状向我暗示,每次都有一些东西被存储在内存中,并在每次子例程

我有一个Fortran数字代码,可以从外部模块调用子程序。在我尝试在另一台机器上编译和运行之前,这段代码一直运行良好。在新机器上,我的程序崩溃得相当快

通过使用debug print语句,我发现崩溃发生在从外部子例程返回时。主程序多次调用子例程,在第二次调用子例程返回时发生崩溃(第一次调用工作正常)。它总是在使用这组输入数据的第二个子例程调用时崩溃,但在使用另一组输入数据(大约是第一组的1/3)时,它在从第五个子例程调用返回时崩溃

这些症状向我暗示,每次都有一些东西被存储在内存中,并在每次子例程调用中累积,直到它耗尽空间,但我不确定这是什么,也不确定它是如何发生的。代码很难简化为一个最小的工作示例,但我已经在下面发布了相关部分。如果有其他有助于了解的内容,请告诉我。它基本上是固定格式的Fortran 90

         use fd

         implicit none

         integer, parameter :: ms = 2000
         integer n
         real(dp), dimension(ms) :: s
         real(dp), dimension(ms) :: e
         real(dp), dimension(ms) :: f
         real(dp), dimension(ms) :: d1f
         real(dp), dimension(ms) :: d2f
         real(dp), dimension(ms) :: c, d
         real(dp), dimension(ms) :: a
         real(dp), dimension(ms) :: b
         real(dp), dimension(ms) :: temp
         integer w
         integer k
         real(dp) th

         do i = 1,n
           temp(i) = a(i)
         end do
         call lprsmf(s(1:n),temp(1:n),n,w,k,th,a(1:n),d1f(1:n),
      *               d2f(1:n))

         do i = 1,n
           temp(i) = b(i)
         end do
         call lprsmf(s(1:n),temp(1:n),n,w,k,th,b(1:n),d1f(1:n),
      *               d2f(1:n))

         do i = 1,n
           temp(i) = c(i)
         end do
         call lprsmf(s(1:n),temp(1:n),n,w,k,th,c(1:n),d1f(1:n),
      *               d2f(1:n))

         do i = 1,n
           temp(i) = d(i)
         end do
         call lprsmf(s(1:n),temp(1:n),n,w,k,th,d(1:n),d1f(1:n),
      *               d2f(1:n))

         do i = 1,n
           temp(i) = e(i)
         end do
         call lprsmf(s(1:n),temp(1:n),n,w,k,th,e(1:n),d1f(1:n),
      *               d2f(1:n))

         do i = 1,n
           temp(i) = f(i)
         end do
         call lprsmf(s(1:n),temp(1:n),n,w,k,th,f(1:n),d1f(1:n),
      *               d2f(1:n))
模块
fd

      module fd
        ! Double precision real kind
        integer, parameter :: dp = selected_real_kind(15)

      contains

      subroutine lprsmf(x,y,n,w,k,th,s,d1,d2)
!       INPUTS:
!         x, y, n, w, k, th
!       OUTPUTS:
!         s, d1, d2

        implicit none

        real(dp), dimension(n) :: x,y,s,d1,d2
        integer n,w,k
        real(dp) th

!     ... code here ...

      end subroutine lprsmf

      end module fd
我的编译器是gfortran 4.6.1。除了让代码停止崩溃之外,我真的很想了解参数传递的基本情况(因为我假设问题在于从程序中传递数组片段)。请注意,
a、b、c、d、e、f、s、temp、d1f、d2f
的长度为2000,而表示有效数据范围的
n
的长度为100-500,具体取决于输入数据的长度


编辑:错误消息是Windows弹出一个对话框,通知我程序已停止工作。

感谢所有人帮助解决此问题。我遵循并编译了
-O2-fimplicit none-Wall-Wline truncation-Wcharacter truncation-Wsurprising-Waliasing-Wimplicit interface-Wunused参数-fwhole file-fcheck=all-fbacktrace
。这揭示了我在子程序中包含的其他人的旧F77代码中存在内存泄漏。显然,某些内部数组的长度比需要的长度短1项。我解决了这个问题,现在一切似乎都正常了。

我的第一个想法是绝对确定你传递给例程的real确实是双精度的,正如例程所要求的那样。更准确地说,确保例程希望在其dp参数中看到什么字节大小(可能是8,但不一定),并确保与传递的实际参数的字节大小相同。不同的编译器处理实数的精度不同。好的,如果您确定所有声明都是100%一致的,那么精度不是问题。我能想到的另一件事是分割错误。很多时候,故障点与代码中的bug实际所在的位置无关。我发现导致seq错误的两个最常见的原因是写入超出了数组的界限,而且输入参数列表与子例程期望的输入变量类型之间不匹配(听起来不像是坏记录)。您可以通过使用数组边界检查进行编译来跟踪前者。您正在“使用”包含子例程lprsmf的模块,该模块来自调用它的程序?使用gfortran尝试最大限度的调试选项,例如:-O2-fimplicit none-Wall-Wline truncation-Wcharacter truncation-Wsurprising-Waliasing-Wimplicit interface-Wunused parameter-fwhole file-fcheck=all-fbacktraceHi,您能用程序崩溃时收到的实际错误消息更新您的问题吗,这是一个错误吗?我肯定要做的第一件事是遵循M.S.B.的建议,或者至少使用'-fcheck=bounds'(使用gfortran)。至于do循环,我认为它们是等效的。关于
n
的价值,我的观点是,您没有给我们提供一个[简短、自包含的代码示例](sscce.org/),这使得我们很难追踪到底发生了什么。你能用一个复制错误的最小完整程序更新你的问题吗?