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))

2 番目の を削除しALLOCATEます。

次回自分でデバッグするには、次-gのようにオプションを付けてコンパイルします。

$ gfortran -g code.f95

デバッガーで実行します。

$ gdb a.out
gdb> run

その後、クラッシュの場所が表示されます。

于 2011-04-12T23:27:06.847 に答える
4

ここで発生しているバス エラーは、temparray を割り当てる前に、numarray から temparray にコピーすることによって発行されます。ループに入る前に行 ALLOCATE(temparray(numrolls)) を移動するだけです。

バス エラーに関する適切なコメントについては、セグメンテーション違反を参照してください。

于 2011-04-12T23:27:56.207 に答える