我尝试通过嵌套在另一个函数(下面的代码)中的两个函数(“ wer”和“ qwe”)来调用FITPACK库的子例程SPLEV。
在已编译程序的执行中会出现以下消息:
QWE
程序接收到的信号SIGSEGV:分段错误-无效的内存引用。
此错误的回溯:
0 0x7F3EE4BF3E08
1 0x7F3EE4BF2F90
2 0x7F3EE453A4AF
3 0x4041B6 in splev _
值为4 0x400BD0.f90时为3386:?
在MAIN__中的5 0x400A6B在pr.f90:?
Ошибкасегментирования(сделандамппамяти)
如果我使用标志-g -fbacktrace -fsanitize=address,zero,undefined
编译程序,则会显示以下输出消息:
QWE
0.37051690837706980
程序接收到的信号SIGSEGV:分段错误-无效的内存引用。
此错误的回溯:
0 0x7FAB5F45CE08
1 0x7FAB5F45BF90
2 0x7FAB5EDA34AF
splev_中的3 0x4075F0在splev.f:73(判别器2)
4 0x400DDE value.3386在pr.f90:87
qwe.3406中的5 0x400FFA在pr.f90:43
在wer.3403中的6 0x400F88在f.90:48
在MAIN__中的7 0x400D08在pr.f90:38
Ошибкасегментирования(сделандамппамяти)
如果我使用标志-g -fbacktrace -Wall -fcheck=all
编译程序,则会显示以下输出消息:
QWE
程序接收到的信号SIGSEGV:分段错误-无效的内存引用。
此错误的回溯:
0 0x7F2BE6F0FE08
1 0x7F2BE6F0EF90
2 0x7F2BE68564AF
splev_中的3 0x4075F0在splev.f:73(判别器2)
4 0x400DDE value.3386在pr.f90:87
在MAIN__中的5 0x400C46在f.90:35
Ошибкасегментирования(сделандамппамяти)
如果我使用标志-g -fbacktrace -fsanitize=address
编译程序,则会显示以下输出消息:
QWE
ASAN:SIGSEGV
================================================ ==================
== 4796 ==错误:AddressSanitizer:未知地址上的SEGV 0x000000000000(PC 0x000000408f67 bp 0x7ffe7a134440 sp 0x7ffe7a1341e0 T0)
splev_ /home/yurchvlad/Science/Coll_Int/F90/f90DP/1/splev.f:0 0x408f66:73
值1 0x40145d.3386(/ home / yurchvlad / Science / Coll_Int / F90 / f90DP / 1 / curfit + 0x40145d)
2 0x4011a3 intcoll /home/yurchvlad/Science/Coll_Int/F90/f90DP/1/pr.f90:35
主/home/yurchvlad/Science/Coll_Int/F90/f90DP/1/pr.f90:2中的3 0x401849
__ libc_start_main中的4个0x7fcad9b3282f(/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
_start中的5 0x400d38(/ home / yurchvlad / Science / Coll_Int / F90 / f90DP / 1 / curfit + 0x400d38)
AddressSanitizer无法提供其他信息。
摘要:地址消毒剂:SEGV /home/yurchvlad/Science/Coll_Int/F90/f90DP/1/splev.f:73 splev _
== 4796 ==正在终止
首先,我将显示代码,然后提供有关库FITPACK的子例程CURFIT和SPLEV的一些信息,这些子例程在其中起主要作用。
这是我的代码。这只是一个测试程序,也就是说,我可以在其中插入解析函数的值数组,这不是混乱。
PROGRAM IntColl
USE Constants
IMPLICIT NONE
INTEGER :: i, nen ! i = counter
! nen, nmn, ne is sirvice variables, which
! appear on exit of CURFIT and needed on entry
! of SPLEV and SPLINT
REAL(DP) :: foo
REAL(DP) :: MOM1 ! dimensionless neutrino momentum
REAL(DP) :: dmg ( 1 : 2 * NG) ! dimensionless momentum grid
REAL(DP) :: endf( 1 : 2 * NG) ! electron neutrino distribution function
! muon neutrino distribution function
! electron and positron distribution function
REAL(DP) :: ten ( 1 : 2 * NG + k + 1) ! service arrays:
! ten is array arising on exit of working of CURFIT
! and contain knots of the spline (for endf, mndf and edf correspondingly).
REAL(DP) :: cen ( 1 : 2 * NG + k + 1) ! needed on entry of SPLEV and SPLINT
! cen appear on exit of CURFIT, contain coefficients of spline
! (for endf, mndf and edf correspondingly) and needed on entry of SPLEV and SPLINT.
REAL(DP) :: w ( 1 : 2 * NG + k + 1) ! w is array of weights for points on entry of CURFIT.
DO i = 1, 2 * NG
dmg(i) = i / 10.D+00 ! filling arrays to give their
endf(i) = eq_nu_di_fu(dmg(i)) ! on entry into subroutine
w(i) = 1.d+00 ! CURFIT
END DO
MOM1 = .53D+00
PRINT *, 'QWE'
CALL spline(dmg, endf, nen, ten, cen)
foo = value(MOM1, ten, nen, cen)
PRINT *, foo
PRINT *, wer(MOM1)
CONTAINS
REAL(DP) FUNCTION qwe(q) ! qwe and wer is "wrappers" for using
REAL(DP) :: q ! of subroutines spline > curfit
qwe = value(q, ten, nen, cen) ! in main program
END FUNCTION qwe
REAL(DP) FUNCTION wer(q)
REAL(DP) :: q
wer = qwe(q)
END FUNCTION wer
SUBROUTINE spline(x, y, n, t, c) ! spline is "hand-made wrapper" for
IMPLICIT NONE ! more convenient using of subroutine
! CURFIT in main program
INTEGER :: m, nest, n, lwrk, ier
INTEGER, PARAMETER :: iopt = 0
INTEGER :: iwrk( 1 : 10 * NG )
REAL(DP) :: xb, xe, fp
REAL(DP) :: wrk( 1 : 2 * NG * (k + 1) + (2 * NG + k + 1) * (7 + 3 * k) )
REAL(DP) :: x( 1 : 2 * NG), y(1: 2 * NG )
REAL(DP) :: t( 1 : 2 * NG + k + 1 )
REAL(DP) :: c( 1 : 2 * NG + k + 1 )
xb = 0.d+00
xe = x(2 * NG)
m = 2 * NG
nest = m + k + 1
lwrk = 2 * NG * (k + 1) + nest * (7 + 3 * k)
CALL curfit(iopt, m, x, y, w, xb, xe, k, s, nest, n, t, c, fp, wrk, lwrk, iwrk, ier)
END SUBROUTINE spline
REAL(DP) FUNCTION value(q, t, n, c) ! value is "hand-made wrapper" for
IMPLICIT NONE ! more convenient using of subroutine
! SPLEV in main program
INTEGER :: n, ier ! SPLEV should work only after
INTEGER, PARAMETER :: m = 1 ! CURFIT edned its working
REAL(DP) :: q
REAL(DP) :: t( 1 : 2 * NG + k + 1 )
REAL(DP) :: c( 1 : 2 * NG + k + 1 )
REAL(DP) :: ddmg(1), sddmg(1)
ddmg(1) = q
CALL splev(t, n, c, k, ddmg, sddmg, m, ier)
value = sddmg(1)
END FUNCTION value
REAL(DP) FUNCTION eq_nu_di_fu(y) ! eq_nu_di_fy givev values for array
IMPLICIT NONE ! to interpolate
REAL(DP) :: y
eq_nu_di_fu = 1 / (EXP(y) + 1)
END FUNCTION eq_nu_di_fu
END PROGRAM IntColl
模块常量存在于其中:
MODULE CONSTANTS
INTEGER, PARAMETER :: DP = SELECTED_REAL_KIND(15, 307)
INTEGER, PARAMETER :: NG = 200 ! NUMBER OF KNOTS OF GRID
INTEGER , PARAMETER :: K = 3 ! THE ORDER OF SPLINE
REAL(DP), PARAMETER :: S = 0.D+00 ! CUBIC SPLINE SMOOTHING FACTOR
END MODULE
现在,上述代码中出现的子例程CURFIT和SPLEV及其所有依赖关系都位于以下来源:
https://github.com/jbaayen/fitpackpp/tree/master/fitpack
这些子例程的精度为双精度
和
http://www.netlib.org/dierckx/
这些子例程具有单精度。
非常重要的一点是,上述方案具有单精度功能!
当然,如果我使用单精度子例程,则会以相应的方式修改所有变量的所有类型。
我还观察到了什么
直接使用FUNCTION值即可。
如果行 打印*,'QWE' 在主程序的注释中,也不会显示值'foo'。