我从我的机器上得到了对我的Fortran95代码的奇怪反应,并且不知道出了什么问题。情况如下:
我正在尝试熟悉LAPACK并编写了一个可耻的简单1-D“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)会发生变化。我可能在这里犯了一个菜鸟错误,但我现在感到很无助,因为它有时会 并且我不确定如何解释Backtrace。
目前我的想法是:
以前是否有人经历过这样的事情,可以提供任何有关目的的建议?
提前致谢,欢呼,
N.F。
答案 0 :(得分:1)
您将b
定义为一维实数组并将其分配
堆。您将它作为第6个参数传递给SGESV
。
documentation of SGESV
将第6个参数定义为2维实数组:
\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
寻址的二维数组中,实际上它们可能会幸运地发生
躺在你实际通过的1D数组中,或者不知道谁知道什么
程序内存布局的其他部分。所以它破坏了自己。该
造成的伤害将无法预测,并会根据您的输入而有所不同
参数,它确定错误分配的预期和实际大小
阵列。
将您的代码与SGESV
的文档化界面进行比较,您会看到
混淆参数B
和IPIV
。