Fortran : erreurs de segmentation

De Wiki de Calcul Québec
Aller à : Navigation, rechercher
Autres langues :anglais 100% • ‎français 100%

Une erreur fréquemment observée avec un exécutable Fortran provient de problèmes d'interface. Ces problèmes surviennent lorsque l'on transmet comme argument d'une sous-routine un pointeur, un tableau alloué dynamiquement ou encore un pointeur de fonctions. À la compilation il n'y a pas de problèmes, cependant à l'exécution vous obtiendrez par exemple le message suivant :

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

Pour corriger le problème, il faut s'assurer que l'interface de la sous-routine est définie explicitement. Ceci peut se faire en Fortran par l'utilisation de la commande INTERFACE. Ainsi le compilateur arrivera à construire l'interface et les erreurs de segmentation seront réglées.


Dans le cas où l'argument est un tableau allouable, il s'agit de remplacer le code suivant :

Fichier : erreur_allocate.f90
Program Eigenvalue
implicit none
 
integer                       :: ierr
integer                       :: ntot
real, dimension(:,:), pointer :: matrice
integer, external             :: genmat
 
read(5,*) ntot
ierr = genmat( ntot, matrice )
 
call Calcul_Eigenvalue( ntot, matrice )
 
deallocate( matrice )
end


par ce qui suit :

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


Le principe est le même dans le cas où l'argument est un pointeur de fonction. Considérons, par exemple, le code suivant :

Fichier : erreur_pointeur.f90
Program AireSousLaCourbe
implicit none
 
real,parameter :: borneInf = 0.
real,parameter :: borneSup = 1.
real           :: aire
real, external :: calculIntegral
real, external :: FunctionAIntegrer
 
aire = calculIntegral( FunctionAIntegrer, borneInf, borneSup )
 
end
 
function FunctionAIntegrer( x )
implicit none
 
real             :: FunctionAInteger
real, intent(in) :: x
 
FunctionAIntegrer = x
 
end function FunctionAIntegrer
 
function calculIntegral( func, borneInf, borneSup )
implicit none
 
real, external   :: func
real, intent(in) :: borneInf, borneSup
 
...


Pour ne pas obtenir d'erreur de segmentation, il faut remplacer le code précédent par ce qui suit :

Fichier : interface_pointeur.f90
Program AireSousLaCourbe
implicit none
 
real,parameter :: borneInf = 0.
real,parameter :: borneSup = 1.
real           :: aire
real, external :: calculIntegral
 
interface
    function FunctionAIntegrer( x )
    implicit none
    real             :: FunctionAIntegrer
    real, intent(in) :: x
    end function FunctionAIntegrer
end interface
 
aire = calculIntegral( FunctionAIntegrer, borneInf, borneSup )
 
end
 
 
function FunctionAIntegrer( x )
implicit none
 
real             :: FunctionAInteger
real, intent(in) :: x
 
FunctionAIntegrer = x
 
end function FunctionAIntegrer
 
 
function calculIntegral( func, borneInf, borneSup )
implicit none
 
real, intent(in) :: borneInf, borneSup
 
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