Funções do ponteiro Fortran:por que o comportamento desse código depende da ordem das chamadas de função?

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

Pergunta

Contexto

O código Fortran de brinquedo postado abaixo chama duas funções de ponteiro.Ou seja, ambas as funções retornam um ponteiro.Na verdade, ambos são ponteiros de array.Ambos tentam fazer a mesma coisa, que é retornar um ponteiro de array inteiro referenciando um array inteiro com três elementos, 1, 2 e 3.A primeira função usa o operador de atribuição de ponteiro (=>) para apontar o ponteiro da função para uma matriz alocável que contém os dados.A segunda função aloca um bloco de memória dinâmica diretamente, através do ponteiro, para armazenar os dados.O programa de chamada apenas imprime os elementos do(s) array(s) retornado(s).

Aqui está o que acho estranho.

  1. Se eu apontar a ao resultado de function1, os resultados não estão corretos.O primeiro elemento a parece estar "derrotado": a tem 0, 2, 3.
  2. Se eu apontar b ao resultado de function2, os resultados estão corretos. b recebe 1, 2, 3.
  3. Mais estranho ainda, apontando b ao resultado de function2 depois apontando a para function1 mudanças a tal que se torne correto. a então tem 1, 2, 3.

Pergunta

Por que isso ocorre?Mais precisamente, por que uma função de ponteiro que retorna um ponteiro para um array alocável supera o primeiro elemento desse array para o chamador?Mais precisamente ainda, por que apontar um ponteiro (b) produzem um efeito colateral em outro ponteiro (a), onde os alvos vêm de funções diferentes que são escritas de forma a não interagirem entre si?

Ressalvas

Recebo esse comportamento usando o compilador GNU Fortran v.4.3.3, executando um laptop Intel com Ubuntu (Jaunty).Seus resultados podem variar, o que pode ser ainda mais interessante.Finalmente, como sempre, pode ser um erro do operador da minha parte, o que seria interessante para mim, pelo menos.

Código

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
Foi útil?

Solução

Variável variedade de function1 é uma variável local - porque é declarada sem o atributo "save", não é persistente e é indefinida quando a função é encerrada.Você atribui o endereço de variedade para function1, "mantendo" este endereço, mas o endereço não é significativo quando a variável se torna indefinida após sair da função.Uma implementação provável é que variedade da função1 será colocada na pilha e essa área da pilha será liberada para outros usos quando a função1 retornar.Mas isso é apenas um palpite sobre uma implementação provável - o ponto principal é que você não tem permissão para usar o valor do ponteiro depois que a variável se torna indefinida.Variáveis ​​alocáveis ​​são automaticamente desalocadas quando saem do escopo, a menos que você as declare com o atributo "save".

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top