2

我的 Fortran 程序可以编译,但随后我收到一个奇怪的错误,称为“总线错误”。

这是我的全部代码。我真的可以使用一些帮助。有谁知道我怎样才能摆脱这个错误并让我的程序正常工作?

我正在尝试生成一个通过随机数创建的数组,然后让该数组进行一些统计。

    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
4

3 回答 3

5

它看起来像是temparray在分配之前使用的。

回答您的问题“什么是总线错误?” :这通常意味着你的程序试图访问一个不存在的地址,或者一个没有与该架构正确对齐的地址(例如,试图从一个未对齐的 4 字节的倍数的地址读取 32 位值)。

于 2011-04-12T23:20:16.620 回答
4

你的配置temparray来不及了。试试这个:

ALLOCATE(numarray(numexps,numrolls), temparray(numrolls))

并删除第二个ALLOCATE.

下次要自己调试,请使用-g选项编译,如下所示:

$ gfortran -g code.f95

并在调试器下运行它:

$ gdb a.out
gdb> run

然后它将为您提供崩溃的位置。

于 2011-04-12T23:27:06.847 回答
4

您在这里遇到的总线错误是通过在分配 temparray 之前从 numarray 复制到 temparray 发出的。只需在进入循环之前移动 ALLOCATE(temparray(numrolls)) 行。

有关总线错误的良好评论,请参阅Segmentation fault

于 2011-04-12T23:27:56.207 回答