Fortran 程序接收信号SIGBUS:访问内存对象的未定义部分
我有这个简单的Fortran代码和一个函数,我在主程序中显式地提供了一个参数。代码如下:Fortran 程序接收信号SIGBUS:访问内存对象的未定义部分,fortran,runtime-error,gfortran,bus-error,Fortran,Runtime Error,Gfortran,Bus Error,我有这个简单的Fortran代码和一个函数,我在主程序中显式地提供了一个参数。代码如下: implicit none real*8 rrr,x external tttt x = rrr(10) end function rrr(seed) integer seed, k real*8 rrr k = 7 seed = 16807 * ( seed - k * 127773 ) - (k * 2836) print*,se
implicit none
real*8 rrr,x
external tttt
x = rrr(10)
end
function rrr(seed)
integer seed, k
real*8 rrr
k = 7
seed = 16807 * ( seed - k * 127773 ) - (k * 2836)
print*,seed
rrr = seed / 2.
end
它进行编译,但在运行时会产生以下错误:
Program received signal SIGBUS: Access to an undefined portion of a memory object.
Backtrace for this error:
#0 0x10f43bfe6
#1 0x10f43b7ac
#2 0x7fff89740529
#3 0x10f433d78
#4 0x10f433e2c
#5 0x10f433e6e
Bus error: 10
知道是什么导致了这个错误吗?我使用gfortran编译代码。您正在修改函数中的种子。您不能这样做,因为它是常量
10
。如果传递了不可定义的内容,则不能在函数中修改seed
。常量文字是不可定义的。变量通常为
另外,不要使用外部函数。使用模块,或将函数放入“包含”部分,使其成为内部函数。这样,调用方将具有显式接口,并可以检查代码的正确性
特别是,如果使用函数参数intent(In)
并检查接口,则可以自动避免所犯的错误。即使没有模块,如果启用所有警告和错误检查,许多编译器也可以发现问题。例如,gfortran中的-g-fcheck=all-Wall-fbacktrace
为您修复:
real*8 :: x
integer :: iseed
iseed = 10
x = rrr(iseed)
contains
function rrr(seed)
real*8 :: rrr
integer, intent(in) :: seed
integer :: kk
k = 7
seed = 16807 * ( seed - k * 127773 ) - (k * 2836)
print *,seed
rrr = seed / 2.
end function
end program
@Vladimir F,很抱歉我是个外行,但是我该如何解决这个问题呢?@user3578925您可以将所需的内容作为变量传递,或者对伪参数使用
value
属性,或者创建本地副本。我很确定我们最近看到了一个非常类似/有用的问题,但我无法立即找到它。但是对于value
您需要明确的接口。好的,如果我使用y=10,然后执行“x=rrr(y)”就行了。老实说,我不明白。我可以用显式数字调用子例程,也就是说,我可以“调用任何东西(10,输出)”,只要在子例程中将数字10定义为整数,这就行了。问题是你在函数内部修改它!不能修改常量文本10
。您必须简单地接受这一点,这是一条Fortran规则。real*8
不是有效的Fortran,也从来不是任何ISO Fortran标准的一部分。