Fortran:调用返回未知大小向量和数组的子例程

时间:2014-03-13 11:25:33

标签: memory-management segmentation-fault fortran subroutine

我在调用返回向量和大小未知的数组的子函数时遇到问题。我不知道如何去掉我称之为函数的变量。该程序确实编译,但崩溃并显示错误消息:

  

Minnesegmentsfeil(核心倾销)

这就像英语中的内存分段错误。

这是我的主要计划。

program transfer
!  use konstanter
  implicit none

! real :: f3eksitasjon
! real :: amp, w, F3a, eta3a

  real, allocatable, dimension(:) :: Aw, Vp, Vtot, Ym, Zm, Zt, Ds
  real, allocatable, dimension(:,:) :: Spos
  integer, allocatable, dimension(:) :: Ns, Dir
  integer :: i, N


  call geometry(N, Aw, Vp, Vtot, Ym, Zm, Zt, Ds, Ns, Spos, DIR)

  print *, N, Aw(1), Vp(1), Vtot(1), Ym(1), Zm(1), Ds(1), Ns(1), Spos(1,1), Spos(1,2), Dir(1)


end program transfer

子程序几何从文件中读取。向量的长度和数组的大小取决于它读取的文件。

subroutine geometry(N, Aw, Vp, Vtot, Ym, Zm, Zt, Ds, Ns, Spos, DIR)
  implicit none

  integer, intent(out) :: N
  real, dimension(:), allocatable, intent(out):: Aw, Vp, Vtot, Ym, Zm, Zt, Ds
  real, dimension(:,:), allocatable, intent(out) :: Spos
  integer, dimension(:),allocatable, intent(out) :: Ns, DIR
  real, dimension(:), allocatable :: Bp, Hp, Lp, Vs
  real, parameter :: pi = 4.0*atan(1.0) 
  integer :: i


  open(unit = 11, file = "semisub.dat")
  read(11,*) N

  allocate(Aw(N))
  allocate(Vp(N))
  allocate(Vtot(N))
  allocate(Ym(N))
  allocate(Zm(N))
  allocate(Zt(N))
  allocate(Ds(N))
  allocate(Spos(N,4))
  allocate(Ns(N))
  allocate(DIR(N))
  allocate(Hp(N))


  do i = 1,N
     read(11,*) Bp(i), Hp(i), Lp(i), Ym(i), Zm(i), DIR(i)
     read(11,*) Ns(i), Ds(i)

     If (Ns(i) > 8) STOP "Feil i semisub.dat. For mange sOyler"

     read(11,*) Spos(i,1:Ns(i))


  end do

  Zt(:) = Zm(:) + Hp(:)/2
  Aw(:) = 2 * Ds(:) * Ns(:)
  Vp(:) = 2 * Lp(:) * Bp(:) * Hp(:)
  Vs(:) = 2 * Ns(:) * pi * (Ds/2)**2 * (-Zt(:))
  Vtot(:) = Vp(:) + Vs(:)


end subroutine geometry

1 个答案:

答案 0 :(得分:3)

如图所示,代码缺少主程序范围内子例程的显式接口。该子例程需要显式接口,因为某些参数是可分配的。

(如果显式接口可用,则意味着编译器显式知道子例程的接口是什么样的 - 编译器需要此信息,因为它通常需要执行额外的工作来将可分配对象传递给可分配的伪参数。 )

将子程序放在一个模块中然后在主程序的规范部分中使用该模块是为子程序提供显式接口的一种方法。另一种方法是使子例程成为一个内部过程(将它放在主程序中的contains语句之后)。第三种方法是将子程序的接口块放在主程序的规范部分中。

相关问题