我有这个程序,我想用程序重写它,怎么了?
program matrix
implicit none
integer(4)::m=1500
real(8),allocatable::a(:,:),b(:,:),c(:,:)
integer(4)::i,j,k
allocate(a(m,m),b(m,m),c(m,m))
c(m,m)=0
c=matmul(a,b)
end program matrix
我尝试过:
module mat
contains
subroutine ma(a,b,c)
real(8),intent(in) :: a(:,:),b(:,:)
real(8),intent(out) :: c(:,:)
integer(4) :: m
c(m,m)=0
c=matmul(a,b)
end subroutine
end module
program matrix
use mat
implicit none
integer(4)::m=1500
real(8),allocatable::a(:,:),b(:,:),c(:,:)
integer(4)::i,j,k
allocate(a(m,m),b(m,m),c(m,m))
call ma(a,b,c)
end program matrix
编译很好,但是程序的漂洗导致错误:
程序接收到的信号SIGSEGV:分段错误-无效的存储器引用。
Backtrace for this error:
#0 0x7fce39df731a
#1 0x7fce39df6503
#2 0x7fce39a29f1f
#3 0x560354451a98
#4 0x5603544520ef
#5 0x560354452132
#6 0x7fce39a0cb96
#7 0x5603544517a9
#8 0xffffffffffffffff
Neoprávněný přístup do paměti (SIGSEGV) (core dumped [obraz paměti uložen])
(将Francescalus和我本人的评论汇总在一起)
您的主要问题是您正在使用例程m
中未初始化的ma
。因为m
是例程的局部变量,所以它与代码中的任何其他变量都没有关系,因此从没有明确定义的值开始。这些bug很难找到,但是可以适当地使用运行时检查,例如-fcheck = all(对于gfortran)和-checkall(对于Intel编译器),并且打开编译时警告可以帮助您对其进行跟踪。
在此之上,我强烈建议您避免使用种类值的文字常量。关于为什么这是一个坏主意,本网站上有很多解释,这里是Fortran 90 kind parameter
将它们组合在一起,我会像这样编写您的程序
ijb@ianbushdesktop ~/work/stack $ cat mat.f90
Module numbers_module
Implicit None
Integer, Parameter, Public :: wp = Selected_real_kind( 12, 70 )
Private
End Module numbers_module
Module mat_module
Use numbers_module, Only : wp
Implicit None
Public :: mat
Private
Contains
Subroutine mat( a, b, c )
Real( wp ), Dimension( :, : ), Intent( In ) :: a
Real( wp ), Dimension( :, : ), Intent( In ) :: b
Real( wp ), Dimension( :, : ), Intent( Out ) :: c
Integer :: m
m = Size( a, Dim = 1 )
c( m, m ) = 0.0_wp
c = Matmul( a, b )
End Subroutine mat
End Module mat_module
Program matrix
Use numbers_module, Only : wp
Use mat_module , Only : mat
Implicit None
Real( wp ), Dimension( :, : ), Allocatable :: a
Real( wp ), Dimension( :, : ), Allocatable :: b
Real( wp ), Dimension( :, : ), Allocatable :: c
Integer :: m = 1500
Allocate( a( 1:m, 1:m ) ) ! Should really check allocation worked
Allocate( b( 1:m, 1:m ) )
Allocate( c( 1:m, 1:m ) )
Call Random_number( a )
Call Random_number( b )
Call Random_number( c )
Call mat( a, b, c )
Write( *, * ) c( m, m ) ! Make sure work is not optimised away
End Program matrix
ijb@ianbushdesktop ~/work/stack $ gfortran --version
GNU Fortran (GCC) 7.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ijb@ianbushdesktop ~/work/stack $ gfortran -O -std=f2003 -Wall -Wextra -fcheck=all mat.f90
ijb@ianbushdesktop ~/work/stack $ ./a.out
383.37740061088573
ijb@ianbushdesktop ~/work/stack $