سؤال

This is kind of a follow up to questions to Fortran array with dynamic size, as easy the R function seq() , which I asked previoulsy, in the sense that I still get the same error when I run the program:

Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

Backtrace for this error:
#0  0x7F13E6FD87D7
#1  0x7F13E6FD8DDE
#2  0x7F13E6929FEF
#3  0x4014B6 in fillmatrix_
#4  0x40270E in MAIN__ at dyn.f90:?
Segmentation fault (core dumped)

I made slight changes to the program:

program dyn
implicit none
real(kind=8), allocatable    :: k(:), tt1(:), p(:)      
real(kind=8), allocatable    :: fitness(:,:), k_opt(:,:)               
real(kind=8)                 :: dk = 0.1, dp = 0.1      
integer                      :: j,l,m,lk,lp,lt          
external                         :: derivate, fillmatrix  


k = 0.1*dk*[(j,j=0,999)]   ! vector of basal expression levels
p = 0.4*dp*[(l,l=1,1000)]  ! vector of period lengths
tt1 = 0.1*dk*[(m,m=0,999)] ! vector of values for T1/T

lk = size(k)
lp = size(p)
lt = size(tt1)

call fillmatrix(k,p,tt1,lk, lp, lt, fitness, k_opt)

end program dyn


subroutine fillmatrix(k,p,tt1,size_k, size_p, size_tt1, fitness, k_opt)
    implicit none
    integer, intent(in)          :: size_k, size_p, size_tt1
    real(kind=8)                 :: k(size_k), p(size_p), tt1(size_tt1)
    real(kind=8), allocatable    :: results(:), t(:)
    real(kind=8)                 :: num = 10, t0,t1,t2,t3         
    real(kind=8)                 :: periode, laenge, basal, lenge 
    real(kind=8)                 :: dt = 0.1
    real(kind=8), dimension(6)   :: q0, x_new, res               
    real(kind=8), dimension(6)   :: u0,f1,f2,f3,u1, k1,k2,k3,k4   
    real(kind=8), dimension(size_k,size_tt1), intent(out)   :: fitness
    real(kind=8), dimension(size_p, size_tt1), intent(out)  :: k_opt
    integer                      :: i,j,l,m,n,o,q,r,posi          

    open(unit = 10,file = '3D.txt', status = 'unknown') ! save data in .txt file
    do n=1, size(p)
    periode = p(n)        ! set period length

    do o=1,size(tt1)
        laenge = tt1(o)   ! set turning point T1/T

        do q=1,size(k)
            basal = k(q)  ! set level of basal expression

            lenge = 10*num*periode         
            t = 0.1*dt*[(i,i=0,INT(lenge))]

            ! initial conditions vector q0
            q0(1) = 0     ! x
            q0(2) = basal ! y
            q0(3) = 0     ! z
            q0(4) = 0     ! a
            q0(5) = 1     ! b
            q0(6) = 0     ! w

            x_new = q0 ! set initial conditions


            do r = 1, size(t)
                call derivate(basal,periode,laenge,t(r),x_new,k1) 

                t1 = t(o) + dt/2      
                f1 = x_new + (dt*k1)/2
                call derivate(basal,periode,laenge,t1,f1,k2)      

                t2 = t(o) + dt/2      
                f2 = x_new + (dt*k2)/2
                call derivate(basal,periode,laenge,t2,f2,k3)      

                t3 = t(o) + dt
                f3 = x_new + (dt*k3)/2
                call derivate(basal,periode,laenge,t3,f3,k4)      

                res = x_new + (dt*(k1+2*k2+2*k3+k4))/6
                if (res(2) < basal) then
                    res(2) = basal
                endif
                results = res(6)                     
                fitness(q,o) = maxval(results)/lenge 
            end do

        end do
        posi = maxloc(fitness(o,:),1) 
        k_opt(o,n) = k(posi)       
    end do
end do
write(10,*) k_opt              
end subroutine fillmatrix

I have tried to find the cause of the error for several hours now, but am no closer to finding it.

هل كانت مفيدة؟

المحلول

At your call to fillmatrix not all of your arrays are allocated. This is not legal because they are explicit size arguments and they do not have the right shape (or any shape in fact). This is the case of the array fitness and k_opt.

Because you are a beginner, couple of advices:

  • Use debugging options. For example, gfortran -Wall -fcheck=all -g -fbacktrace.

    For your program gfortran then writes:

    At line 18 of file test.f90
    Fortran runtime error: Allocatable actual argument 'fitness' is not allocated
    

    when you run the program.

  • Put all your subroutines into a module, this will enable better passing options and checks.

  • After you did that, use assumed shape arrays (:,:,:) as dummy arguments, you will avoid copies that you may encounter with explicit size.

  • Do not use real(kind=8), it is not portable, there are many examples here on SO how to do that. Use a named constant, and get the kind value from selected_real_kind() or from iso_fortran_env modules constants real32 and real64.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top