【问题标题】:Segmentation fault, when passing functions with array arguments to subroutine in Fortran分段错误,将带有数组参数的函数传递给 Fortran 中的子例程
【发布时间】:2013-03-13 23:45:05
【问题描述】:

我正在做一个项目(明天到期:/),当我尝试在我自己编写的函数上使用单纯形算法时遇到了问题。它没有用,经过 5 个小时的搜索和实验,我发现了以下内容:

当我将函数传递给子例程时,该函数不能有任何数组参数。这是真的?因为在我应该使用它的代码中显然应该可以工作。

我正在使用 ifort 编译器。请参阅下面的最小示例,我基本上取自 http://malayamaarutham.blogspot.de/2006/02/passing-function-names-as-arguments-in.html

  ! Author : Kamaraju S Kusumanchi
  ! Email  : kamaraju@gmail.com
  ! Last edited : Sun Feb  5 2006
  !
  ! Sample program demonstrating the use of external attribute.        This program
  ! shows how to pass function names as arguments in Fortran 90       programs.
  !
  ! Compilation and execution steps
  ! $gfortran passing_functions.f90 -o passing_functions
  ! $./passing_functions
  !  beta =    5.500000
  !  beta =    1.500000
  !
  ! I would appreciate any comments, feedback, criticism,       mistakes, errors etc.,
  !   (however minor they are)
  !
  module dummy
    implicit none
  contains
  !------------------------------------------------------------------------------
  function func1(a)
    implicit none
    real :: a
    real :: func1

    func1 = a+5
  end function func1
  !------------------------------------------------------------------------------
  function func2(b)
    implicit none
    real :: b(:)
    real :: func2

    func2 = b(1)
  end function func2
  !------------------------------------------------------------------------------
  function func3(dyn_func, c)
    implicit none
    real :: c
    real, external :: dyn_func
    real :: func3

    func3 = dyn_func(c)
  end function func3
  !------------------------------------------------------------------------------
  function func4(dyn_func, c)
    implicit none
    real :: c(*)
    real, external :: dyn_func
    real :: func4

    func4 = dyn_func(c)
  end function func4
  end module dummy
  !------------------------------------------------------------------------------

  program passing_functions
    use dummy
    implicit none

    real :: alpha=0.5, beta
    real :: gamma(2) = (/10,20/)

    beta = func3(func1, alpha)
    write(*,*) 'beta = ', beta
    beta = func4(func2, gamma)
    write(*,*) 'beta = ', beta
  end program passing_functions

这是输出:

zeus$ passing.out
 beta =    5.500000    
forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image              PC                Routine            Line        Source             
passing.out        0000000000402D44  Unknown               Unknown  Unknown
passing.out        0000000000402C7C  Unknown               Unknown  Unknown
libc.so.6          00002AFF7915D23D  Unknown               Unknown  Unknown
passing.out        0000000000402B79  Unknown               Unknown  Unknown
zeus$ 

【问题讨论】:

标签: arrays function fortran subroutine


【解决方案1】:

其他答案可用于解决您的问题,但有更简单的方法,无需使用指针。

在现代 Fortran 中几乎没有理由使用 external。在我在 Stackoverflow 上看到的 Fortran 问题中,它几乎总是将人们引向错误的方法。除非你很确定,否则不要使用external

您要做的是声明(即描述)函数 func3func4 中的函数参数和 interface 块。这是func4的操作方法...您应该能够弄清楚func3

 function func4(dyn_func, c)
    implicit none
    real, dimension (:) :: c
    interface
       function dyn_func (x)
          real :: dyn_func
          real, dimension (:) :: x
       end function dyn_func
    end interface
    real :: func4

    func4 = dyn_func(c)
  end function func4

【讨论】:

  • ...而需要接口块的具体原因是因为被传递的函数(func2)具有假定的形状参数。然后 OP 将需要处理这样一个事实,即您不能将假定大小的实际参数传递给假定形状的虚拟对象......
  • 完全正确,IanH。在我添加的示例代码中,我也改进了这一点,但没有提及...
  • 哦,哇,太好了!它适用于简单的东西,现在我将尝试将其用于其余部分。老实说,我不得不承认我之前读过另一个答案,但我仍然不明白那里的一个词:) 我会查一下这些接口是什么,但现在我很高兴它起作用了,那又是 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-15
  • 2013-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-15
  • 1970-01-01
相关资源
最近更新 更多