如何使用程序重写程序?

问题描述 投票:0回答:1

我有这个程序,我想用程序重写它,怎么了?

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])
fortran procedure
1个回答
0
投票

(将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 $ 
© www.soinside.com 2019 - 2024. All rights reserved.