Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Array allocation (error: Integer Overflow)

Status
Not open for further replies.

uetian304

Technical User
Aug 17, 2011
2
DE
Hi all,
I am new to Fortran programming. My work is concentrated on arrays.
After writing a subroutine for simple multiplication of 2 arrays (1 dimensional), when I used it, the compiler gave an error:
" Fortran runtime error: Integer overflow when calculating the amount of memory to allocate "
I am surprised to see this error, because I think this subroutine is very clear and simple.
Please give me a hint about the cause of error.
---------------------------------------------------------

subroutine dyad(A, B, C)
real, intent(in) :: A:))
real, intent(in) :: B:))
real, dimension:),:), intent(out) :: C
real, dimension:),:), allocatable :: D
integer :: i, j, na, nb
na=size(A)
nb=size(B)
allocate(D(na,nb))
do i=1,na
do j=1,nb
D(i,j)=A(i)*B(j)
end do
end do
C=D
end subroutine dyad
 
I did some changes in the code, but this time a different error occurred:
error: "Segmentation fault (core dumped)"

The code is:
----------------------------
subroutine dyad(A, B, C)
real, intent(in) :: A:))
real, intent(in) :: B:))
real, dimension(size(A),size(B)), intent(out) :: C
integer :: i, j
do i=1,size(A)
do j=1,size(B)
C(i,j)=A(i)*B(j)
end do
end do
end subroutine dyad

----------------------------
 
Just as a matter of interest, which compiler are you using? I tried it with Silverfrost and got the same results as you.

Basically, the problem is size does not work on subroutine arguments. Whenever you hit problems like these, if you don't know how to use the debugger or you do not have access to a debugger, just use print statements.

You could fix it in the old fashioned way by passing the sizes of the arrays in. This will only work if C is the correct shape (have a look at the use of shape to reshape your arrays)
Code:
program main
    real a(10), b(5), c(10,5)
    a = 65.0 ! anything random
    b = 66.0 ! any random value
    print *, 'main a size=', size(a,1)
    print *, 'main b size=', size(b,1)
    call dyad (a, size(a,1), b, size(b,1), c)
    print *, 'It worked'
    stop
end

subroutine dyad (a, na, b, nb, c)
    real, intent(in):: a(:)
    real, intent(in):: b(:)
    integer, intent(in):: na, nb
    real, intent(out):: c(:,:)
    real, dimension(:,:), allocatable:: d
    
    integer:: i, j
    
    print *, 'allocating ', na, ' by ', nb
    allocate(d(na,nb))
    print *, 'allocation worked'
    do i = 1, na
       do j = 1, nb
          d(i,j) = a(i) * b(j)
       end do
    end do
    print *, 'filled up array'
    c = d
    print *, 'assigned array'
end subroutine dyad

Your modified method won't work because size is still returning the wrong answer.
 
put your subroutine into a module please, and use that module in the calling procedure. Then your program will work automagically. Indeed, you need an explicit interface when an argument is declared with :)) or :),:). Using a module is the easiest way to declare that explicit interface. Another way is an INTERFACE block but this one is error prone because it must duplicate exactly the signature of the subroutine.

Example based on the programming proposed by xwb:

Code:
module container
contains
subroutine dyad (a, na, b, nb, c)
    real, intent(in):: a(:)
    real, intent(in):: b(:)
    integer, intent(in):: na, nb
    real, intent(out):: c(:,:)
    real, dimension(:,:), allocatable:: d
    
    integer:: i, j
    
    print *, 'allocating ', na, ' by ', nb
    allocate(d(na,nb))
    print *, 'allocation worked'
    do i = 1, na
       do j = 1, nb
          d(i,j) = a(i) * b(j)
       end do
    end do
    print *, 'filled up array'
    c = d
    print *, 'assigned array'
end subroutine dyad
end module container

program main
    use container
    real a(10), b(5), c(10,5)
    a = 65.0 ! anything random
    b = 66.0 ! any random value
    print *, 'main a size=', size(a,1)
    print *, 'main b size=', size(b,1)
    call dyad (a, size(a,1), b, size(b,1), c)
    print *, 'It worked'
    stop
end

Result :

Code:
[lcoul@localhost test]$ ifort t54.f90
[lcoul@localhost test]$ ./a.out
 main a size=          10
 main b size=           5
 allocating           10  by            5
 allocation worked
 filled up array
 assigned array
 It worked
 (/code]

François Jacq
 
FJacq, I think you missed the point - my program will work regardless of whether it is in a module because that is how we used to do it to get round size not working inside a subroutine.

However, your suggestion does work with uetians program. size works when it is inside a module.
Code:
module container
contains
subroutine dyad (a, b, c)
    real, intent(in):: a(:)
    real, intent(in):: b(:)
    integer:: na, nb
    real, intent(out):: c(:,:)
    real, dimension(:,:), allocatable:: d
    
    integer:: i, j
    
    na = size(a,1)
    nb = size(b,1)
    print *, 'allocating ', na, ' by ', nb
    allocate(d(na,nb))
    print *, 'allocation worked'
    do i = 1, na
       do j = 1, nb
          d(i,j) = a(i) * b(j)
       end do
    end do
    print *, 'filled up array'
    c = d
    print *, 'assigned array'
end subroutine dyad
end module container

program main
    use container
    real a(10), b(5), c(10,5)
    a = 65.0 ! anything random
    b = 66.0 ! any random value
    print *, 'main a size=', size(a,1)
    print *, 'main b size=', size(b,1)
    call dyad (a, b, c)
    print *, 'It worked'
    stop
end
 
OK xwb, you are partly right. I copied your subroutine instead of copying the one of the OP :)

But you should also notice that your version is not correct as well, even if it seems to work : you lie about the interface of the subroutine. A "segmentation fault" (or any other strange behavior) could occur with another compiler...

The right version of the subroutine should be (with a subroutine outside a module and without explicit interface block) :

Code:
subroutine dyad (a, na, b, nb, c)
    real, intent(in):: a(na) ! or a(*)
    real, intent(in):: b(nb) ! or b(*)
    integer, intent(in):: na, nb
    real, intent(out):: c(na,nb) ! or c(na,*)

    real, dimension(:,:), allocatable:: d ! this array is useless
    
    integer:: i, j
    
    print *, 'allocating ', na, ' by ', nb
    allocate(d(na,nb))
    print *, 'allocation worked'
    do i = 1, na
       do j = 1, nb
          d(i,j) = a(i) * b(j) ! c(i,j)=a(i)*b(j) is simpler
       end do
    end do
    print *, 'filled up array'
    c = d
    print *, 'assigned array'
end subroutine dyad

François Jacq
 
Yes - thanks, forgot about 2D arrays.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top