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.
- Si je signale
a
au résultat defunction1
, les résultats ne sont pas corrects. Le premier élément dea
semble être "clobé":a
a0
,2
,3
. Si je pointeb
au résultat defunction2
, les résultats sont corrects.b
obtient1
,2
,3
. - étrange encore, pointant
b
le résultat defunction2
après pointant versa
-function1
changea
telle qu'elle est correcte.a
a ensuite1
,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
Parfait! Je vous remercie! –