不一致:调用 LAPACK 的 SGESV 子程序时进程中止或分段错误或 运行 正常

inconsistent: process abort or segmentation fault or running fine when calling LAPACK's SGESV subroutine

我的 machine 对我的 Fortran95 代码有奇怪的反应,我不知道出了什么问题。情况是这样的:

我正在尝试熟悉 LAPACK 并编写了一个可耻的简单一维 "FEM" 程序只是为了看看如何使用 LAPACK:

program bla
! Solving the easiest of all FE static cases: one-dimensional, axially loaded elastic rod. composed of 2-noded elements



implicit none


integer :: nelem, nnodes, i,j, info
real, parameter :: E=2.1E9, crossec=19.634375E-6, L=1., F=10E3
real :: initelemL
real, allocatable :: A(:,:)
real, allocatable :: b(:), u(:)
integer, allocatable :: ipiv(:)



print *,'Number of elements?'
read *,nelem

nnodes=nelem+1


allocate(A(nnodes,nnodes),u(nnodes),b(nnodes), ipiv(nnodes))
initelemL=L/nelem



A(1,1)=1
do i=2, nnodes
A(1,i)=0
end do

do i=2,nnodes
do j=1,nnodes
A(i,j)=0
end do
A(i,i)=1
A(i,i-1)=-1
end do

b(1)=0   !That's the BC of zero-displacement of the first node
do i=2,nnodes
b(i)=((F/crossec)/E +1)*initelemL
end do



!calling the LAPACK subroutine:


call SGESV(nnodes,nnodes, A, nnodes, ipiv, b, nnodes, info)
print *,info
print *,b

end program bla

我在 mac 所以为了包括 LAPACK 我编译: gfortran -fbacktrace -g -Wall -Wextra -framework 加速 bla.f95

没有警告。

当我运行代码时,奇怪的事情发生了:

如果我输入 2 作为元素数量,我会得到预期的答案 "b"。

如果我输入 5,则会出现分段错误:

Number of elements?
5    

           0

Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

Backtrace for this error:
#0  0x10bd3eff6
#1  0x10bd3e593
#2  0x7fff98001f19
#3  0x7fff93087d62
#4  0x7fff93085dd1
#5  0x7fff930847e3
#6  0x7fff93084666
#7  0x7fff93083186
#8  0x7fff9696c63f
#9  0x7fff96969393
#10  0x7fff969693b4
#11  0x7fff9696967a
#12  0x7fff96991bb2
#13  0x7fff969ba80e
#14  0x7fff9699efb4
#15  0x7fff9699f013
#16  0x7fff9698f3b9
#17  0x10bdc7cee
#18  0x10bdc8fd6
#19  0x10bdc9936
#20  0x10bdc0f42
#21  0x10bd36c40
#22  0x10bd36d20
Segmentation fault: 11

如果我输入 50,我得到了答案,但是程序失败了,尽管没有什么可做的:

Number of elements?
50
           0
   0.00000000       2.48505771E-02   4.97011542E-02   7.45517313E-02   9.94023085E-02  0.124252886      0.149103463      0.173954040      0.198804617      0.223655194      0.248505771      0.273356348      0.298206925      0.323057503      0.347908080      0.372758657      0.397609234      0.422459811      0.447310388      0.472160965      0.497011542      0.521862149      0.546712756      0.571563363      0.596413970      0.621264577      0.646115184      0.670965791      0.695816398      0.720667005      0.745517612      0.770368218      0.795218825      0.820069432      0.844920039      0.869770646      0.894621253      0.919471860      0.944322467      0.969173074      0.994023681       1.01887429       1.04372489       1.06857550       1.09342611       1.11827672       1.14312732       1.16797793       1.19282854       1.21767914       1.24252975    
a.out(1070,0x7fff7aa05300) malloc: *** error for object 0x7fbdd9406028: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug

Program received signal SIGABRT: Process abort signal.

Backtrace for this error:
#0  0x106c61ff6
#1  0x106c61593
#2  0x7fff98001f19
Abort trap: 6

这是可重现的。但是:如果我在代码中的某处放置另一个 'print' 语句,数字(这里:2、5、50)会改变。我可能在这里犯了一个菜鸟错误,但我目前感到相当无助,因为它有时有时而且我不确定如何解释回溯。

我目前的想法是:

  1. 使用 SGESV 的一些非常愚蠢的错误
  2. LAPACK 库以某种方式损坏
  3. 我的内存存在一些硬件问题。

有没有人以前经历过类似的事情并且可以就发生的事情提供任何建议?

提前致谢,干杯,

N.F.

您将 b 定义为一维实数数组并将其分配给 堆。您将它作为第 6 个参数传递给 SGESV.

documentation of SGESV 定义第6个参数为二维实数数组:

\param[in,out] B
\verbatim
          B is REAL array, dimension (LDB,NRHS)
          On entry, the N-by-NRHS matrix of right hand side matrix B.
          On exit, if INFO = 0, the N-by-NRHS solution matrix X.
\endverbatim

SGESV 因此写入它认为的内存位置 位于由 b 寻址的二维数组中,但幸运的是,实际上它们可能恰好位于 位于您实际通过的一维数组中,或者不幸地位于谁知道什么中 程序内存布局的其他部分。所以它在破坏自己。这 造成的损害将无法预测,并且会根据您的输入而有所不同 参数,它决定了错误分配的预期和实际大小 数组。

将您的代码与 SGESV 的文档接口进行比较,您似乎 混淆参数 BIPIV.