0

外部モジュールからサブルーチンを呼び出す Fortran 数値コードがあります。このコードは、別のマシンでコンパイルして実行しようとするまで、問題なく動作していました。新しいマシンでは、私のプログラムはすぐにクラッシュします。

debug print ステートメントを使用して、外部サブルーチンからの戻り時にクラッシュが発生することを特定しました。メイン プログラムはサブルーチンを数回呼び出し、サブルーチンへの 2 回目の呼び出しから戻ったときにクラッシュが発生します (最初の呼び出しは正常に機能します)。この入力データのセットを使用した 2 番目のサブルーチン呼び出しで常にクラッシュしますが、別の入力データのセット (最初のサイズの約 1/3) を使用すると、5 番目のサブルーチン呼び出しから戻ったときにクラッシュします。

症状は、何かが毎回メモリに保存され、スペースがなくなるまでサブルーチン呼び出しごとに蓄積されることを示唆していますが、それが何であるか、またはどのように発生するかはわかりません。コードを最小限の作業例に単純化するのは困難ですが、関連する部分を以下に掲載しました。他に何か参考になるものがあれば教えてください。基本的に固定形式の 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 です。

4

1 に答える 1

1

この問題の追跡に協力してくれたすべての人に感謝します。私はMSBの提案に従い、でコンパイルしまし-O2 -fimplicit-none -Wall -Wline-truncation -Wcharacter-truncation -Wsurprising -Waliasing -Wimplicit-interface -Wunused-parameter -fwhole-file -fcheck=all -fbacktraceた。これにより、サブルーチンに含めた他の誰かの古い F77 コードにメモリ リークがあることが明らかになりました。どうやら、一部の内部配列が、長さ 1 項目よりも短い長さで宣言されているようです。私はそれを修正しました、そして今はすべてうまくいくようです。

于 2012-08-02T18:31:31.137 に答える