Fortran Bus Error on allocating a large matrix (gfortran)

1.5k views Asked by At

When I compile the following Fortran code with gfortran and run it, it gives me 'signal SIGBUS: Access to undefined portion of a memory object', whenever n>=180. I'm running this on a Mac OSX Mavericks.

PROGRAM almatrix
  IMPLICIT NONE
  INTEGER :: i,j,n
  REAL,ALLOCATABLE :: a(:,:)
  READ(*,*)n
  ALLOCATE(a(n+1,n+1))
  DO i=0,n
    DO j=0,n
      a(i,j)=0.0
    END DO
  END DO
  DEALLOCATE(a)
END PROGRAM almatrix

I understood that instead of

ALLOCATE(a(n+1,n+1))

this

ALLOCATE(a(n+1,n+1),STAT=err)
IF(err /= 0) STOP

would prevent crashing. It didn't, however. Why? I tried to look at similar problems, but so far they haven't helped. I tried to compile with -Wall, -g, -fcheck=all, as suggested in another answer, but those didn't give me warnings.

I've also noticed before, that unlike with C, Fortran usually does not give bus errors when using small dynamic arrays and not deallocating them.

1

There are 1 answers

2
francescalus On BEST ANSWER

The problem isn't directly with the allocate statement, but with accessing the resulting array. [Note also that that an array 181x181 is not "large".] As there is nothing wrong with the allocation, err will indeed be zero.

From that allocate one is left with an array a which has elements a(1,1), a(2,1), ..., a(n+1,1), ..., a(n+1,n+1). So, a(0,0) (the first access in the loop) is not valid.

There are two options: request that the array elements be a(0,0) to a(n,n) as the loop wants, or change the loop:

allocate(a(0:n,0:n))

or

do i=1,n+1
  do j=1,n+1
    a(j,i) = 0  ! Note I've changed the order to Fortran-friendly
  end od
end do

Finally, those loops aren't even necessary:

allocate(a(0:n,0:n))
a = 0.

or even

allocate(a(0:n,0:n), source=0.)

if you have a compiler later than Fortran 95.