Fortran 90 w / Cygwin:分段错误(核心转储)

时间:2013-06-30 00:09:57

标签: cygwin fortran gfortran fault

直到最近我决定学习自由形式的Fortran时,我已经在Matlab中完成了所有编程。我将gfortran编译器与Cygwin一起使用。我有兴趣编写可以将数组作为输入,对其进行计算,然后将新数组传回的函数。我从没想过这是一项艰巨的任务,但无论如何,它确实至少对我来说已经证明了这一点。这是我的简单测试代码:

    PROGRAM RETURN_ARRAY
! Description: This program is used to test a function that returns
!              an array.

    REAL*8 :: NROOT

    PRINT *, NROOT(2, [1.0D0, 4.0D0, 9.0D0, 16.0D0, 25.0D0])

END PROGRAM RETURN_ARRAY


FUNCTION NROOT(N, X) RESULT(Y)
! Description: This function calculates the Nth root of a real number
!              or array of real numbers.
!
! Inputs: N - desired Nth root
!         X - real number or array of real numbers to take Nth root of
!
! Outputs: Y - Nth root of real number or array of real numbers, X

    INTEGER, INTENT(IN) :: N
    REAL*8, INTENT(IN)  :: X(:)
    REAL*8              :: P
    REAL*8              :: Y(SIZE(X))

    P = 1.0D0/N
    Y = X**P

END FUNCTION NROOT

`我编译这个程序和内部函数如下:

gfortran RETURN_ARRAY.f90 -o MAIN.exe

程序编译没有错误。但是,当我尝试运行程序时,我在终端中得到了这个输出:

Segmentation fault (core dumped)

感谢您解决此问题的任何帮助。提前谢谢。

1 个答案:

答案 0 :(得分:0)

当我尝试编译(Fedora 18上的gfortran 4.8)时,我首先遇到错误,这是

Warning: Type mismatch in argument 'n' at (1); passed REAL(8) to INTEGER(4)

所以有第一个错误。将2.d0更改为2,我收到以下错误

Error: Procedure 'nroot' at (1) with assumed-shape dummy argument 'x' must have an explicit interface

所以这是另一个错误。只需使用contains结构(见下文),我得到以下结果:

   1.0000000000000000        2.0000000000000000        3.0000000000000000        4.0000000000000000        5.0000000000000000

所以看起来你的问题是双重的:你错误地匹配变量类型&错误地声明一个函数。以下是您的代码应该是什么样的(没有评论):

PROGRAM RETURN_ARRAY
    PRINT *, NROOT(2, [1.0D0, 4.0D0, 9.0D0, 16.0D0, 25.0D0])
  CONTAINS
    FUNCTION NROOT(N, X) RESULT(Y)
       INTEGER, INTENT(IN) :: N
       REAL*8, INTENT(IN)  :: X(:)
       REAL*8              :: P
       REAL*8              :: Y(SIZE(X))

       P = 1.0D0/N
       Y = X**P

    END FUNCTION NROOT
END PROGRAM RETURN_ARRAY

编辑

顺便说一下,我还有另外两条建议:

(1)使用REAL*8是不好的做法,因为它是编译器和/或系统相关的。您应该使用INTEGER, PARAMETER :: dp = SELECTED_REAL_KIND(14, 100)(此处14表示有效小数位数,100表示最大指数)。然后,您可以将变量定义为REAL(dp) :: PREAL(KIND=dp) :: PP = 1.0_dp/N

(2)您应在IMPLICIT NONE之后声明PROGRAM <name>。这样,任何未显式声明的变量都会停止编译器。