什么是“总线错误”我的 Fortran 代码中的什么触发了它?
我的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
看起来
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).
您在这里遇到的总线错误是在分配 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.
您对
temparray
的分配已经太晚了。试试这个:然后删除第二个
ALLOCATE
。要下次自己调试它,请使用
-g
选项进行编译,如下所示:并在调试器下运行它:
然后它会给您崩溃的位置。
Your allocation of
temparray
is too late. Try this:and delete the second
ALLOCATE
.To debug it yourself next time, compile with
-g
option, like this:and run it under a debugger:
it will then give you the location of the crash.