Search code examples
arraysfortranbus

What is a 'Bus error' and what in my Fortran code triggers it?


My Fortran program compiles, but then I get a weird error called 'Bus error.'

Here is my code in its entirety. I could really use some help. Does anyone know how I can get rid of this error and get my program to work fine?

I'm trying to generate an array created via random numbers and then have the array undergo some statistics.

    PROGRAM numbersgen
IMPLICIT NONE

    !Variable declaration
    INTEGER, DIMENSION(:,:),ALLOCATABLE::numarray
    INTEGER, DIMENSION(:),ALLOCATABLE::temparray
    INTEGER:: numrolls, numexps
    INTEGER:: i=0, j=0
    REAL:: avg=0, sdv=0, variance=0, sum=0
    INTEGER:: k, min, pos, temp
    
    
    PRINT*, "Enter the number of experiments to simulate: "
    READ*, numexps
    
    PRINT*, "Enter the number of rolls per experiment: "
    READ*, numrolls
    
    ALLOCATE(numarray(numexps,numrolls))
    
    DO i=1, numexps
        CALL GenerateNum(numarray, numrolls, numexps)
        
        DO j=1, numrolls
            temparray(j)=numarray(i,j)
        END DO
    
        PRINT*, "Experiment ",i
        
        CALL Sorter(temparray, numrolls)
        CALL ComputeStats(temparray, sum, avg, variance, sdv)
        CALL PrintStats( sum, avg, variance, sdv)       
    END DO
    
    ALLOCATE(temparray(numrolls))
    
    CONTAINS
    
    SUBROUTINE GenerateNum(numarray, numrolls, numexps)
    
    INTEGER, INTENT(IN):: numrolls, numexps
    INTEGER, INTENT(OUT):: numarray(numexps, numrolls)
    REAL:: R1
    
    CALL RANDOM_SEED()
    DO i=1, numexps
        DO j=1, numrolls
    CALL RANDOM_NUMBER(R1)
    numarray(i,j)=1+INT(6*R1)
        END DO
    END DO
    
    
    
    
    !commented out for now
    !PRINT*, " "
    !PRINT*, "Unsorted"
    !DO i=1, numrolls
    !WRITE(*,23,ADVANCE="NO") temparray(i)
    !23 FORMAT (I2)
    !END DO
    !PRINT*," "
    END SUBROUTINE
    
    SUBROUTINE Sorter(temparray, numrolls)
    
    INTEGER, INTENT(OUT):: temparray(numrolls)
    INTEGER, INTENT(IN):: numrolls
    
    DO i=1, (numrolls-1)
        min=temparray(i)
        pos=i
        DO k=i,numrolls
            IF (temparray(k)<min)THEN
                min=temparray(k)
                pos=k
            END IF
        END DO
        temp=temparray(i)
        temparray(i)=min
        temparray(pos)=temp
    END DO
    PRINT*, "Sorted Numbers"
    DO i=1, numrolls
    WRITE(*,23,ADVANCE="NO") temparray(i)
    23 FORMAT (I2)
    END DO
    PRINT*, " "
    END SUBROUTINE
    
    
    
    
    SUBROUTINE ComputeStats(temparray, sum, avg, variance, sdv)
    
    INTEGER, INTENT(IN):: temparray(numrolls)
    REAL, INTENT(OUT):: sum
    REAL, INTENT(OUT):: avg, variance, sdv
    
    DO i=1, numrolls
    sum=sum+temparray(i)
    END DO
    
    avg=sum/numrolls
    
    DO i=1, numrolls
    variance=variance+(((temparray(i)-avg)**2.0)/10)
    END DO
    sdv=variance**0.5
    
    END SUBROUTINE
    
    
    
    SUBROUTINE PrintStats( sum, avg, variance, sdv)
    
    
    REAL, INTENT(IN):: sum
    REAL, INTENT(IN):: avg, variance, sdv
    
    PRINT*, " "
    PRINT*, "Sum: ",sum
    PRINT '(1X,A,F5.3)', "Average: ",avg
    PRINT '(1X,A,F5.3)', "Variance: ",variance
    PRINT '(1X,A,F5.3)', "Standard Deviation: ",sdv
    
    END SUBROUTINE
    


    
END PROGRAM

Solution

  • The bus error you're getting here is issued by copying from numarray to temparray, before you allocate temparray. Just move the line ALLOCATE(temparray(numrolls)) before you enter the loop.

    For a good comment about bus error, see Segmentation fault.