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
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.