2009-10-16 3 views
1

Contexte

Le code jouet Fortran affiché ci-dessous appelle deux fonctions de pointeur. C'est-à-dire que les deux fonctions renvoient un pointeur. En fait, ils sont tous les deux des pointeurs de tableau. Ils tentent tous les deux de faire la même chose, renvoyer un pointeur de tableau entier référençant un tableau d'entiers ayant trois éléments, 1, 2 et 3. La première fonction utilise l'opérateur d'assignation de pointeur (=>) pour pointer le pointeur de fonction sur un tableau allocatable qui contient les données. La seconde fonction alloue directement un bloc de mémoire dynamique, via le pointeur, pour stocker les données. Le programme appelant imprime simplement les éléments du (des) tableau (s) renvoyé (s).Fonctions du pointeur Fortran: pourquoi le comportement de ce code dépend-il de l'ordre des appels de fonction?

Voici ce que je trouve étrange.

  1. Si je signale a au résultat de function1, les résultats ne sont pas corrects. Le premier élément de a semble être "clobé": a a 0, 2, 3. Si je pointe b au résultat de function2, les résultats sont corrects. b obtient 1, 2, 3.
  2. étrange encore, pointant b le résultat de function2après pointant vers a-function1changea telle qu'elle est correcte. a a ensuite 1, 2, 3.

Question

Pourquoi cela se produit? Plus précisément, pourquoi une fonction de pointeur qui retourne un pointeur sur un tableau allouable clobber le premier élément de ce tableau pour l'appelant? Plus précisément encore, pourquoi pointer un pointeur (b) produit-il un effet secondaire sur un autre pointeur (a), où les cibles proviennent de différentes fonctions écrites pour ne pas interagir les unes avec les autres?

Avertissements

Je reçois ce comportement en utilisant le compilateur GNU Fortran v.4.3.3, l'exécution d'un ordinateur portable Intel avec Ubuntu (Jaunty). Vos résultats peuvent varier, ce qui pourrait être encore plus intéressant. Enfin, comme toujours, il pourrait s'agir d'une erreur de l'opérateur de ma part, ce qui m'intéresserait au moins.

code

program main 
    implicit none 
    integer, dimension(:), pointer :: a, b 
    integer :: i 
    a => function1() 
    b => function2() 
    do i = 1, 3 
    print *, a(i) 
    end do 
    ! do i = 1, 3 
    ! print *, b(i) 
    ! end do 
contains 
    function function1() 
    integer, dimension(:), allocatable, target :: array 
    integer, dimension(:), pointer :: function1 
    allocate(array(3)) 
    array(1) = 1 
    array(2) = 2 
    array(3) = 3 
    function1 => array 
    end function function1 

    function function2() 
    integer, dimension(:), pointer :: function2 
    allocate(function2(3)) 
    function2(1) = 1 
    function2(2) = 2 
    function2(3) = 3 
    end function function2 
end program main 

Répondre

4

variable tableau de function1 est une variable locale - car elle est déclarée sans l'attribut « sauver », il ne persiste pas et est définie lors de la sortie de fonction. Vous affectez l'adresse tableau à function1, "en conservant" cette adresse, mais l'adresse n'est pas significative une fois que la variable devient indéfinie après avoir quitté la fonction. Une implémentation probable est que tableau de la fonction1 sera placé sur la pile, et cette zone de la pile sera libérée pour d'autres utilisations lorsque la fonction1 revient.Mais ce n'est qu'une supposition sur une implémentation probable - le point clé est que vous n'êtes pas autorisé à utiliser la valeur du pointeur après que la variable ne soit indéfinie. Les variables attribuables sont automatiquement désaffectées lorsqu'elles sont hors de portée à moins que vous ne les déclariez avec l'attribut "save".

+0

Parfait! Je vous remercie! –

Questions connexes