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

Memory management Fortran:返回未知大小向量和数组的调用子例程,memory-management,segmentation-fault,fortran,subroutine,Memory Management,Segmentation Fault,Fortran,Subroutine,调用返回未知大小的向量和数组的子函数时遇到问题。我不知道如何清除调用函数的变量。程序确实编译,但崩溃并显示错误消息: Minnesegmentsfeil(堆芯倾倒) 这有点像英语中的记忆分割错误 这是我的主要节目 program transfer ! use konstanter implicit none ! real :: f3eksitasjon ! real :: amp, w, F3a, eta3a real, allocatable, dimension(:) :: A

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

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

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

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


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

下面是一个如何安排代码的示例,以便主程序“知道”如何调用子例程,如IanH所述:在主程序中分配维度(:)是否仍然正确,因为主程序不知道子程序返回的维度?是的。如果数组维度在编译时未知,则使用
allocatable
属性进行声明。分配可以在子例程中完成,但主例程必须知道维度是“可变的”。
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