什么是“总线错误”我的 Fortran 代码中的什么触发了它?

发布于 2024-11-01 15:38:10 字数 3081 浏览 7 评论 0原文

我的 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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

水溶 2024-11-08 15:38:10

看起来 temparray 在分配之前就被使用了。

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

It looks like temparray is used before it is allocated.

To answer your question "what is a bus error?" : it generally means that your program tried to access a nonexistent address, or an address that doesn't have the proper alignment
for that architecture (e.g. trying to read a 32-bit value from an address that's not aligned on a multiple of 4 bytes).

九公里浅绿 2024-11-08 15:38:10

您在这里遇到的总线错误是在分配 temparray 之前从 numarray 复制到 temparray 时发出的。只需移动线即可
分配(临时数组(numrolls))
在进入循环之前。

有关总线错误的详细评论,请参阅分段错误

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.

陪我终i 2024-11-08 15:38:10

您对 temparray 的分配已经太晚了。试试这个:

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

然后删除第二个ALLOCATE

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

$ gfortran -g code.f95

并在调试器下运行它:

$ gdb a.out
gdb> run

然后它会给您崩溃的位置。

Your allocation of temparray is too late. Try this:

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

and delete the second ALLOCATE.

To debug it yourself next time, compile with -g option, like this:

$ gfortran -g code.f95

and run it under a debugger:

$ gdb a.out
gdb> run

it will then give you the location of the crash.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文