分段错误 - 无效的内存引用
Segmentation fault - invalid memory reference
嘿,我正在尝试让我的 LAPACK 库正常工作,我搜索了又搜索,但我似乎无法弄清楚我做错了什么。
我尝试 运行 我的代码,但出现以下错误
程序收到信号 SIGSEGV:分段错误 - 内存引用无效。
Backtrace for this error:
#0 0x7FFB23D405F7
#1 0x7FFB23D40C3E
#2 0x7FFB23692EAF
#3 0x401ED1 in sgesv_
#4 0x401D0B in MAIN__ at CFDtest.f03:? Segmentation fault (core dumped)
我会把我的主要代码贴在这里,希望有人能帮我解决这个问题。
****************************************************
PROGRAM CFD_TEST
USE MY_LIB
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
DIMENSION ET(0:10), VN(0:10), WT(0:10)
DIMENSION SO(0:10), FU(0:10), DMA(0:10,0:10)
DIMENSION DMA2(0:10,0:10), QN(0:10), WKSPCE(0:10)
INTEGER*8 :: pivot(10), inf
INTEGER*8 :: N
EXTERNAL SGESV
!SET THE PARAMETERS
SIGMA1 = 0.D0
SIGMA2 = 0.D0
TAU = 1.D0
EF = 1.D0
EXP = 2.71828182845904509D0
COST = EXP/(1.D0+EXP*EXP)
DO 1 N=2, 10
!COMPUATION OF THE NODES, WEIGHTS AND DERIVATIVE MATRIX
CALL ZELEGL(N,ET,VN)
CALL WELEGL(N,ET,VN,WT)
CALL DMLEGL(N,10,ET,VN,DMA)
!CONSTRUCTION OF THE MATRIX CORRESPONDING TO THE
!DIFFERENTIAL OPERATOR
DO 2 I=0, N
DO 2 J=0, N
SUM = 0.D0
DO 3 K=0, N
SUM = SUM + DMA(I,K)*DMA(K,J)
3 CONTINUE
OPER = -SUM
IF(I .EQ. J) OPER = -SUM + TAU
DMA2(I,J) = OPER
2 CONTINUE
!CHANGE OF THE ENTRIES OF THE MATRIX ACCORDING TO THE
!BOUNDARY CONDITIONS
DO 4 J=0, N
DMA2(0,J) = 0.D0
DMA2(N,J) = 0.D0
4 CONTINUE
DMA2(0,0) = 1.D0
DMA2(N,N) = 1.D0
!CONSTRUCTION OF THE RIGHT-HAND SIDE VECTOR
DO 5 I=1, N-1
FU(I) = EF
5 CONTINUE
FU(0) = SIGMA1
FU(N) = SIGMA2
!SOLUTION OF THE LINEAR SYSTEM
N1 = N + 1
CALL SGESV(N,N,DMA2,pivot,FU,N,inf)
DO 6 I = 0, N
FU(I) = SO(I)
6 CONTINUE
PRINT *, pivot
1 CONTINUE
RETURN
END PROGRAM CFD_TEST
*****************************************************
我运行编译的命令是
gfort运行 -c MY_LIB.f03
gfort运行 -c CFDtest.f03
gfort运行 MY_LIB.o CFDtest.o -o CFDtest -L/usr/local/lib -llapack -lblas
我运行命令
-fbacktrace -g -Wall -Wextra CFDtest
CFDtest: 在函数中 _fini':
(.fini+0x0): multiple definition of
_fini'
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crti.o:/build/buildd/glibc-2.19/csu/../sysdeps/x86_64/crti.S:80:首先在这里定义
CFDtest:在函数 data_start':
(.data+0x0): multiple definition of
data_start'
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o:(.data+0x0): 首先在这里定义
CFDtest:在函数 data_start':
(.data+0x8): multiple definition of
__dso_handle' 中
/usr/lib/gcc/x86_64-linux-gnu/4.9/crtbegin.o:(.data+0x0): 首先在这里定义
CFDtest:(.rodata+0x0): _IO_stdin_used'
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o:(.rodata.cst4+0x0): first defined here
CFDtest: In function
_start'的多重定义:
(.text+0x0): _start'
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o:(.text+0x0): first defined here
CFDtest: In function
_init'的多重定义:
(.init+0x0): _init'
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crti.o:/build/buildd/glibc-2.19/csu/../sysdeps/x86_64/crti.S:64: first defined here
/usr/lib/gcc/x86_64-linux-gnu/4.9/crtend.o:(.tm_clone_table+0x0): multiple definition of
__TMC_END的多重定义'
CFDtest:(.data+0x10): 首先在这里定义
/usr/bin/ld: CFDtest 错误(.eh_frame);不会创建 .eh_frame_hdr table。
collect2:错误:ld 返回了 1 个退出状态
据我所知,可能存在一些问题:
- 带有
INTEGER*8
的整数可能太长,也许 INTEGER*4
或简单地 INTEGER
会更好
- 您调用
SGESV
双参数而不是 DGESV
- 您的
LDA
参数丢失,因此您的代码可能看起来像 CALL DGESV(N,N,DMA2,N,pivot,FU,N,inf)
但您需要检查这是否是您想要的。
您尚未发布 MY_LIB.f03
的代码,因此我们无法完全按照您提供的方式编译 CFDtest.f03
。
(顺便说一句,通常的命名约定是 .f90
文件中的 f90
不应暗示目标语言版本。相反,.f90
表示自由格式而 .f
用于固定格式。通过扩展,您的 .f03
文件会更好(即,如果更便携)命名为 .f90
。)
我通过 nagfor -u -c cfd_test.f90
注释掉了 USE MY_LIB
行和 运行 你的代码。分解后的输出是
Extension: cfd_test.f90, line 13: Byte count on numeric data type
detected at *@8
Extension: cfd_test.f90, line 15: Byte count on numeric data type
detected at *@8
字节数不可移植。 8 字节整数的 kind
值为 selected_int_kind(18)
。 (同样,您可能希望对双精度数据使用 kind(0.0d0)
种类值。)
Error: cfd_test.f90, line 48: Implicit type for I
detected at 2@I
Error: cfd_test.f90, line 50: Implicit type for J
detected at 2@J
Error: cfd_test.f90, line 54: Implicit type for K
detected at 3@K
Error: cfd_test.f90, line 100: Implicit type for N1
detected at N1@=
你有这些隐式类型,这意味着它们是 4 字节(默认)整数。如果这是您想要的,您可能应该将这些明确声明为 8 字节整数(使用上面的 8 字节整数类型值)。
Questionable: cfd_test.f90, line 116: Variable COST set but never referenced
Questionable: cfd_test.f90, line 116: Variable N1 set but never referenced
Warning: cfd_test.f90, line 116: Unused local variable QN
Warning: cfd_test.f90, line 116: Unused local variable WKSPCE
你需要决定你打算用这些做什么,或者它们是否只是可删除的垃圾。
通过显式声明隐式整数,还有进一步的输出
Warning: cfd_test.f90, line 116: Variable SO referenced but never set
这看起来很糟糕。
Obsolescent: cfd_test.f90, line 66: 2 is a shared DO termination label
你的 DO
循环使用现代 END DO
终止符(不共享!)可能会更好
Error: cfd_test.f90, line 114: RETURN is only allowed in SUBROUTINEs and FUNCTIONs
这显然很容易修复。
对于 LAPACK 调用,这些例程的显式接口来源之一是 NAG Fort运行 库(通过 nag_library
模块)。由于您的真实数据不是单精度的,因此您应该使用 dgesv
而不是 sgesv
。添加 USE nag_library, ONLY: dgesv
并切换到调用 dgesv
而不是 sgesv
,然后如上重新编译,显示
Incorrect data type INTEGER(KIND=4) (expected INTEGER) for argument N (no. 1) of DGESV
所以你确实应该使用默认值(4 字节整数)——至少对于你系统上的 LAPACK 构建,它几乎肯定会使用 4 字节整数。因此,您可能想忘记所有关于 kind
整数的事情,而只使用默认的 integer
类型。更正这个给出
Array supplied for scalar argument LDA (no. 4) of DGESV
所以你确实需要添加这个参数。也许通过 size(DMA2,1)
?
将此参数添加到调用中后,代码编译成功,但如果没有您的 *LEGL
函数定义,我无法通过任何 运行 时间测试。
这是我对你的程序的修改(和漂亮打印)版本
Program cfd_test
! Use my_lib
! Use nag_library, Only: dgesv
Implicit None
Integer, Parameter :: wp = kind(0.0D0)
Real (Kind=wp) :: ef, oper, sigma1, sigma2, tau
Integer :: i, inf, j, k, n, sum
Real (Kind=wp) :: dma(0:10, 0:10), dma2(0:10, 0:10), et(0:10), fu(0:10), &
so(0:10), vn(0:10), wt(0:10)
Integer :: pivot(10)
External :: dgesv, dmlegl, welegl, zelegl
Intrinsic :: kind, size
! SET THE PARAMETERS
sigma1 = 0._wp
sigma2 = 0._wp
tau = 1._wp
ef = 1._wp
Do n = 2, 10
! COMPUATION OF THE NODES, WEIGHTS AND DERIVATIVE MATRIX
Call zelegl(n, et, vn)
Call welegl(n, et, vn, wt)
Call dmlegl(n, 10, et, vn, dma)
! CONSTRUCTION OF THE MATRIX CORRESPONDING TO THE
! DIFFERENTIAL OPERATOR
Do i = 0, n
Do j = 0, n
sum = 0._wp
Do k = 0, n
sum = sum + dma(i, k)*dma(k, j)
End Do
oper = -sum
If (i==j) oper = -sum + tau
dma2(i, j) = oper
End Do
End Do
! CHANGE OF THE ENTRIES OF THE MATRIX ACCORDING TO THE
! BOUNDARY CONDITIONS
Do j = 0, n
dma2(0, j) = 0._wp
dma2(n, j) = 0._wp
End Do
dma2(0, 0) = 1._wp
dma2(n, n) = 1._wp
! CONSTRUCTION OF THE RIGHT-HAND SIDE VECTOR
Do i = 1, n - 1
fu(i) = ef
End Do
fu(0) = sigma1
fu(n) = sigma2
! SOLUTION OF THE LINEAR SYSTEM
Call dgesv(n, n, dma2, size(dma2,1), pivot, fu, n, inf)
Do i = 0, n
fu(i) = so(i)
End Do
Print *, pivot
End Do
End Program
一般来说,如果您使用尽可能好的检查编译器,并且确保您要求它尽可能多地为您诊断,那么您的开发体验将是最愉快的。
嘿,我正在尝试让我的 LAPACK 库正常工作,我搜索了又搜索,但我似乎无法弄清楚我做错了什么。
我尝试 运行 我的代码,但出现以下错误
程序收到信号 SIGSEGV:分段错误 - 内存引用无效。
Backtrace for this error:
#0 0x7FFB23D405F7
#1 0x7FFB23D40C3E
#2 0x7FFB23692EAF
#3 0x401ED1 in sgesv_
#4 0x401D0B in MAIN__ at CFDtest.f03:? Segmentation fault (core dumped)
我会把我的主要代码贴在这里,希望有人能帮我解决这个问题。
****************************************************
PROGRAM CFD_TEST
USE MY_LIB
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
DIMENSION ET(0:10), VN(0:10), WT(0:10)
DIMENSION SO(0:10), FU(0:10), DMA(0:10,0:10)
DIMENSION DMA2(0:10,0:10), QN(0:10), WKSPCE(0:10)
INTEGER*8 :: pivot(10), inf
INTEGER*8 :: N
EXTERNAL SGESV
!SET THE PARAMETERS
SIGMA1 = 0.D0
SIGMA2 = 0.D0
TAU = 1.D0
EF = 1.D0
EXP = 2.71828182845904509D0
COST = EXP/(1.D0+EXP*EXP)
DO 1 N=2, 10
!COMPUATION OF THE NODES, WEIGHTS AND DERIVATIVE MATRIX
CALL ZELEGL(N,ET,VN)
CALL WELEGL(N,ET,VN,WT)
CALL DMLEGL(N,10,ET,VN,DMA)
!CONSTRUCTION OF THE MATRIX CORRESPONDING TO THE
!DIFFERENTIAL OPERATOR
DO 2 I=0, N
DO 2 J=0, N
SUM = 0.D0
DO 3 K=0, N
SUM = SUM + DMA(I,K)*DMA(K,J)
3 CONTINUE
OPER = -SUM
IF(I .EQ. J) OPER = -SUM + TAU
DMA2(I,J) = OPER
2 CONTINUE
!CHANGE OF THE ENTRIES OF THE MATRIX ACCORDING TO THE
!BOUNDARY CONDITIONS
DO 4 J=0, N
DMA2(0,J) = 0.D0
DMA2(N,J) = 0.D0
4 CONTINUE
DMA2(0,0) = 1.D0
DMA2(N,N) = 1.D0
!CONSTRUCTION OF THE RIGHT-HAND SIDE VECTOR
DO 5 I=1, N-1
FU(I) = EF
5 CONTINUE
FU(0) = SIGMA1
FU(N) = SIGMA2
!SOLUTION OF THE LINEAR SYSTEM
N1 = N + 1
CALL SGESV(N,N,DMA2,pivot,FU,N,inf)
DO 6 I = 0, N
FU(I) = SO(I)
6 CONTINUE
PRINT *, pivot
1 CONTINUE
RETURN
END PROGRAM CFD_TEST
*****************************************************
我运行编译的命令是
gfort运行 -c MY_LIB.f03
gfort运行 -c CFDtest.f03
gfort运行 MY_LIB.o CFDtest.o -o CFDtest -L/usr/local/lib -llapack -lblas
我运行命令
-fbacktrace -g -Wall -Wextra CFDtest
CFDtest: 在函数中 _fini':
(.fini+0x0): multiple definition of
_fini'
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crti.o:/build/buildd/glibc-2.19/csu/../sysdeps/x86_64/crti.S:80:首先在这里定义
CFDtest:在函数 data_start':
(.data+0x0): multiple definition of
data_start'
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o:(.data+0x0): 首先在这里定义
CFDtest:在函数 data_start':
(.data+0x8): multiple definition of
__dso_handle' 中
/usr/lib/gcc/x86_64-linux-gnu/4.9/crtbegin.o:(.data+0x0): 首先在这里定义
CFDtest:(.rodata+0x0): _IO_stdin_used'
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o:(.rodata.cst4+0x0): first defined here
CFDtest: In function
_start'的多重定义:
(.text+0x0): _start'
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o:(.text+0x0): first defined here
CFDtest: In function
_init'的多重定义:
(.init+0x0): _init'
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crti.o:/build/buildd/glibc-2.19/csu/../sysdeps/x86_64/crti.S:64: first defined here
/usr/lib/gcc/x86_64-linux-gnu/4.9/crtend.o:(.tm_clone_table+0x0): multiple definition of
__TMC_END的多重定义'
CFDtest:(.data+0x10): 首先在这里定义
/usr/bin/ld: CFDtest 错误(.eh_frame);不会创建 .eh_frame_hdr table。
collect2:错误:ld 返回了 1 个退出状态
据我所知,可能存在一些问题:
- 带有
INTEGER*8
的整数可能太长,也许INTEGER*4
或简单地INTEGER
会更好 - 您调用
SGESV
双参数而不是DGESV
- 您的
LDA
参数丢失,因此您的代码可能看起来像CALL DGESV(N,N,DMA2,N,pivot,FU,N,inf)
但您需要检查这是否是您想要的。
您尚未发布 MY_LIB.f03
的代码,因此我们无法完全按照您提供的方式编译 CFDtest.f03
。
(顺便说一句,通常的命名约定是 .f90
文件中的 f90
不应暗示目标语言版本。相反,.f90
表示自由格式而 .f
用于固定格式。通过扩展,您的 .f03
文件会更好(即,如果更便携)命名为 .f90
。)
我通过 nagfor -u -c cfd_test.f90
注释掉了 USE MY_LIB
行和 运行 你的代码。分解后的输出是
Extension: cfd_test.f90, line 13: Byte count on numeric data type
detected at *@8
Extension: cfd_test.f90, line 15: Byte count on numeric data type
detected at *@8
字节数不可移植。 8 字节整数的 kind
值为 selected_int_kind(18)
。 (同样,您可能希望对双精度数据使用 kind(0.0d0)
种类值。)
Error: cfd_test.f90, line 48: Implicit type for I
detected at 2@I
Error: cfd_test.f90, line 50: Implicit type for J
detected at 2@J
Error: cfd_test.f90, line 54: Implicit type for K
detected at 3@K
Error: cfd_test.f90, line 100: Implicit type for N1
detected at N1@=
你有这些隐式类型,这意味着它们是 4 字节(默认)整数。如果这是您想要的,您可能应该将这些明确声明为 8 字节整数(使用上面的 8 字节整数类型值)。
Questionable: cfd_test.f90, line 116: Variable COST set but never referenced
Questionable: cfd_test.f90, line 116: Variable N1 set but never referenced
Warning: cfd_test.f90, line 116: Unused local variable QN
Warning: cfd_test.f90, line 116: Unused local variable WKSPCE
你需要决定你打算用这些做什么,或者它们是否只是可删除的垃圾。
通过显式声明隐式整数,还有进一步的输出
Warning: cfd_test.f90, line 116: Variable SO referenced but never set
这看起来很糟糕。
Obsolescent: cfd_test.f90, line 66: 2 is a shared DO termination label
你的 DO
循环使用现代 END DO
终止符(不共享!)可能会更好
Error: cfd_test.f90, line 114: RETURN is only allowed in SUBROUTINEs and FUNCTIONs
这显然很容易修复。
对于 LAPACK 调用,这些例程的显式接口来源之一是 NAG Fort运行 库(通过 nag_library
模块)。由于您的真实数据不是单精度的,因此您应该使用 dgesv
而不是 sgesv
。添加 USE nag_library, ONLY: dgesv
并切换到调用 dgesv
而不是 sgesv
,然后如上重新编译,显示
Incorrect data type INTEGER(KIND=4) (expected INTEGER) for argument N (no. 1) of DGESV
所以你确实应该使用默认值(4 字节整数)——至少对于你系统上的 LAPACK 构建,它几乎肯定会使用 4 字节整数。因此,您可能想忘记所有关于 kind
整数的事情,而只使用默认的 integer
类型。更正这个给出
Array supplied for scalar argument LDA (no. 4) of DGESV
所以你确实需要添加这个参数。也许通过 size(DMA2,1)
?
将此参数添加到调用中后,代码编译成功,但如果没有您的 *LEGL
函数定义,我无法通过任何 运行 时间测试。
这是我对你的程序的修改(和漂亮打印)版本
Program cfd_test
! Use my_lib
! Use nag_library, Only: dgesv
Implicit None
Integer, Parameter :: wp = kind(0.0D0)
Real (Kind=wp) :: ef, oper, sigma1, sigma2, tau
Integer :: i, inf, j, k, n, sum
Real (Kind=wp) :: dma(0:10, 0:10), dma2(0:10, 0:10), et(0:10), fu(0:10), &
so(0:10), vn(0:10), wt(0:10)
Integer :: pivot(10)
External :: dgesv, dmlegl, welegl, zelegl
Intrinsic :: kind, size
! SET THE PARAMETERS
sigma1 = 0._wp
sigma2 = 0._wp
tau = 1._wp
ef = 1._wp
Do n = 2, 10
! COMPUATION OF THE NODES, WEIGHTS AND DERIVATIVE MATRIX
Call zelegl(n, et, vn)
Call welegl(n, et, vn, wt)
Call dmlegl(n, 10, et, vn, dma)
! CONSTRUCTION OF THE MATRIX CORRESPONDING TO THE
! DIFFERENTIAL OPERATOR
Do i = 0, n
Do j = 0, n
sum = 0._wp
Do k = 0, n
sum = sum + dma(i, k)*dma(k, j)
End Do
oper = -sum
If (i==j) oper = -sum + tau
dma2(i, j) = oper
End Do
End Do
! CHANGE OF THE ENTRIES OF THE MATRIX ACCORDING TO THE
! BOUNDARY CONDITIONS
Do j = 0, n
dma2(0, j) = 0._wp
dma2(n, j) = 0._wp
End Do
dma2(0, 0) = 1._wp
dma2(n, n) = 1._wp
! CONSTRUCTION OF THE RIGHT-HAND SIDE VECTOR
Do i = 1, n - 1
fu(i) = ef
End Do
fu(0) = sigma1
fu(n) = sigma2
! SOLUTION OF THE LINEAR SYSTEM
Call dgesv(n, n, dma2, size(dma2,1), pivot, fu, n, inf)
Do i = 0, n
fu(i) = so(i)
End Do
Print *, pivot
End Do
End Program
一般来说,如果您使用尽可能好的检查编译器,并且确保您要求它尽可能多地为您诊断,那么您的开发体验将是最愉快的。