Fortran : segmentation faults

De Wiki de Calcul Québec
Aller à : Navigation, rechercher
Cette page est une traduction de la page Fortran : erreurs de segmentation et la traduction est complétée à 100 % et à jour.

Autres langues :anglais 100% • ‎français 100%

An error that is frequently seen with a Fortran program comes from interface problems. These problems surface if a pointer, a dynamically allocated array or even a function pointer is passed as an argument to a subroutine. There are no compile-time problems, but when the program is ran you see for example the following message:

forrtl: severe (174): SIGSEGV, segmentation fault occurred

To correct this problem, you should ensure that the interface of the subroutine is explicitly defined. This can be done in Fortran using the INTERFACE command. Then the compiler can construct the interface and the segmentation faults are fixed.


When the argument is an allocatable array, you should replace the following code:

File : error_allocate.f90
Program Eigenvalue
implicit none
 
integer                       :: ierr
integer                       :: ntot
real, dimension(:,:), pointer :: matrix
 
read(5,*) ntot
ierr = genmat( ntot, matrix )
 
call Compute_Eigenvalue( ntot, matrix )
 
deallocate( matrix )
end


by this code:

File : interface_allocate.f90
Program Eigenvalue
implicit none
 
integer                       :: ierr
integer                       :: ntot
real, dimension(:,:), pointer :: matrix
 
interface
    function genmat( ntot, matrix )
    implicit none
    integer                       :: genmat
    integer, intent(in)           :: ntot
    real, dimension(:,:), pointer :: matrix
    end function genmat
end interface
 
read(5,*) ntot
ierr = genmat( ntot, matrix )
 
call Compute_Eigenvalue( ntot, matrix )
 
deallocate( matrix )
end


The same principle applies when the argument is a function pointer. Consider, for example, the following code:

File : error_=pointer.f90
Program AreaUnderTheCurve
implicit none
 
real,parameter :: boundInf = 0.
real,parameter :: boundSup = 1.
real           :: area
real, external :: computeIntegral
real, external :: FunctionToIntegrate
 
area = computeIntegral( FunctionToIntegrate, boundInf, boundSup )
 
end
 
function FunctionToIntegrate( x )
implicit none
 
real             :: FunctionToIntegrate
real, intent(in) :: x
 
FunctionToIntegrate = x
 
end function FunctionToIntegrate
 
function computeIntegral( func, boundInf, boundSup )
implicit none
 
real, external   :: func
real, intent(in) :: boundInf, boundSup
 
...


To avoid segmentation faults you should replace the above code by the following:

File : interface_pointer.f90
Program Eigenvalue
implicit none
 
real,parameter :: boundInf = 0.
real,parameter :: boundSup = 1.
real           :: area
real, external :: computeIntegral
 
interface
    function FunctionToIntegrate( x )
    implicit none
    real             :: FunctionToIntegrate
    real, intent(in) :: x
    end function FunctionToIntegrate
end interface
 
area = computeIntegral( FunctionToIntegrate, boundInf, boundSup )
 
end
 
 
function FunctionToIntegrate( x )
implicit none
 
real             :: FunctionToIntegrate
real, intent(in) :: x
 
FunctionToIntegrate = x
 
end function FunctionToIntegrate
 
 
function computeIntegral( func, boundInf, boundSup )
implicit none
 
real, intent(in) :: boundInf, boundSup
 
interface
    function func( x )
    implicit none
    real             :: func
    real, intent(in) :: x
    end function func
end interface
 
...


Outils personnels
Espaces de noms

Variantes
Actions
Navigation
Ressources de Calcul Québec
Outils
Partager