如何诊断fortran中的总线错误

Emm*_*bbs 2 fortran

我正在学习如何使用fortran进行一些数据分析.我正在通过以下示例:

program linalg
  implicit none

  real :: v1(3), v2(3), m(3,3)
  integer :: i,j

  v1(1) = 0.25
  v1(2) = 1.2
  v1(3) = 0.2

  ! use nested do loops to initialise the matrix
  ! to the unit matrix
  do i=1,3
     do j=1,3
        m(i,j) = 0.0
     end do
     m(i,j) = 1.0
  end do

  ! do a matrix multiplicationof a vector equivalent to v2i = mij v1j
  do i = 1,3
     v2(i) = 0.0
     do j = 1,3
        v2(i) = v2(i) + m(i,j)*v1(j)
     end do
  end do

  write(*,*) 'v2 = ', v2

end program linalg
Run Code Online (Sandbox Code Playgroud)

我执行的

f95 -o linalg linalg.f90
./linalg
Run Code Online (Sandbox Code Playgroud)

但是,我在终端中收到以下消息:

Bus error
Run Code Online (Sandbox Code Playgroud)

我在网上跟踪的一些链接表明这与未预先定义变量有关,但我确信我已经在此脚本中找不到错误的来源.还有另一个原因我会得到这个错误吗?

Hig*_*ark 6

你的错误就在这里

  do i=1,3
     do j=1,3
        m(i,j) = 0.0
     end do
     m(i,j) = 1.0    ! here be a dragon
  end do
Run Code Online (Sandbox Code Playgroud)

Fortran明确指出,在循环结束后,索引变量的值比循环的最后一次迭代时的值大1.因此,在这种情况下,声明m(i,j) = 1.0将尝试m(1,4)在第一轮,然后m(2,4)等等处理.

有时你会因为尝试在数组范围之外写字而感到"幸运",并且写入会保留在您正在处理的进程的地址空间内."幸运",因为您的程序错误但不会崩溃 - - 这个崩溃是一个更好的情况.bus error建议编译器生成一个写入的地址,它位于任何进程的禁止区域.

您可以通过使用编译器打开"运行时边界检查"来自己找到它.您的编译器文档或其他Q和As在此处将告诉您如何执行此操作.

我会留下你按照自己的意愿解决这个问题,你现在知道规则就能显示出能够解决的每一个迹象.