分段错误 - 无效的内存引用

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 ofdata_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

一般来说,如果您使用尽可能好的检查编译器,并且确保您要求它尽可能多地为您诊断,那么您的开发体验将是最愉快的。