Question

I have a problem calling a subfunction that returns vectors and arrays with unknown size. I dont know how to declear the variables that I call the function with. The program does compile, but crash with error message:

Minnesegmentsfeil (core dumped)

Which is something like Memory segmentation fault in english.

Here is my main program.

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

The subroutine geometry reads from a file. The length of the vectors and size of array is dependent on the file it reads.

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
Was it helpful?

Solution

The code, as shown, lacks an explicit interface for the subroutine in the scope of the main program. An explicit interface is required for that subroutine because some of the arguments are allocatable.

(If an explicit interface is available it means that the compiler explicitly knows what the interface of the subroutine looks like - the compiler needs this information because it typically has to do additional work to pass an allocatable object to an allocatable dummy argument.)

Putting the subroutine in a module and then USEing that module in the specification part of the main program is one way of giving the subroutine an explicit interface. Another way is to make the subroutine an internal procedure (put it after a contains statement in the main program). A third way is to put an interface block for the subroutine in the specification part of the main program.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top