funzioni di puntatore Fortran: perché il comportamento di questo codice dipendono dall'ordine di chiamate di funzione?

StackOverflow https://stackoverflow.com/questions/1580426

Domanda

Contesto

Il codice Fortran giocattolo postato qui sotto chiama due funzioni di puntatore. Cioè, entrambe le funzioni restituiscono un puntatore. In realtà, sono entrambi puntatori array. Entrambi tentativo di fare la stessa cosa, che è quello di restituire un puntatore integer referenziare un array intero avente tre elementi, 1, 2, e 3. La prima funzione utilizza l'operatore di assegnazione puntatore (=>) per puntare il puntatore alla funzione di un array allocatable che contiene i dati. La seconda funzione alloca un blocco di memoria dinamica direttamente, tramite il puntatore, per la memorizzazione dei dati. Il programma chiamante si limita a stampare gli elementi dell'array restituito (s).

Ecco quello che trovo strano.

  1. Se io punto a al risultato di function1, i risultati non sono corretti. Il primo elemento di a sembra essere "rovinati":. a ha 0, 2, 3
  2. Se io punto b al risultato di function2, i risultati sono corretti. b ottiene 1, 2, 3.
  3. Peggio ancora, indicando b al risultato di function2 dopo che punta a a function1 modifiche a tale che diventa corretto. a ha poi 1, 2, 3.

Domanda

Perché si verifica? Più precisamente, perché una funzione puntatore che restituisce un puntatore ad un array allocatable clobber il primo elemento di tale matrice per il chiamante? Più precisamente ancora, perché non indicando un puntatore (b) produrre un effetto collaterale di un altro puntatore (a), in cui gli obiettivi provengono da diverse funzioni che si scrivono in modo da non interagire tra loro a tutti?

Avvertimenti

ottengo questo comportamento usando il compilatore GNU Fortran v.4.3.3, l'esecuzione di un laptop Intel con Ubuntu (Jaunty). I risultati possono variare, che potrebbe essere ancora più interessante. Infine, come sempre potrebbe essere un errore dell'operatore da parte mia, che sarebbe interessante per me, almeno.

Codice

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
È stato utile?

Soluzione

Variabile array di function1 è una variabile locale - perché è stata dichiarata senza l'attributo "salvare", non è persistente e non è definito quando la funzione termina. Si assegna l'indirizzo di array per function1, "mantenere" questo indirizzo, ma l'indirizzo non è significativa una volta la variabile diventa indefinito dopo l'uscita dalla funzione. Un probabile implementazione è che array di function1 sarà posto sullo stack, e quella zona dello stack saranno liberati per altri usi al ritorno FUNCTION1. Ma questa è solo una supposizione ad un probabile implementazione - il punto chiave è che non ti è permesso di utilizzare il valore del puntatore dopo la variabile diventa indefinito. variabili allocatable vengono deallocate automaticamente quando escono di portata meno che non li dichiara con l'attributo "save".

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top