Funciones del puntero Fortran:¿Por qué el comportamiento de este código depende del orden de las llamadas a funciones?

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

Pregunta

Contexto

El código Fortran de juguete publicado a continuación llama a dos funciones de puntero.Es decir, ambas funciones devuelven un puntero.De hecho, ambos son punteros de matriz.Ambos intentan hacer lo mismo, que es devolver un puntero de matriz de enteros que hace referencia a una matriz de enteros que tiene tres elementos, 1, 2 y 3.La primera función utiliza el operador de asignación de puntero (=>) para apuntar el puntero de la función a una matriz asignable que contiene los datos.La segunda función asigna un bloque de memoria dinámica directamente, a través del puntero, para almacenar los datos.El programa que llama simplemente imprime los elementos de las matrices devueltas.

Esto es lo que me parece extraño.

  1. si señalo a al resultado de function1, los resultados no son correctos.El primer elemento de a parece estar "golpeado": a tiene 0, 2, 3.
  2. si señalo b al resultado de function2, los resultados son correctos. b obtiene 1, 2, 3.
  3. Más extraño aún, señalando b al resultado de function2 después apuntando a a function1 cambios a tal que sea correcto. a entonces tiene 1, 2, 3.

Pregunta

¿Por qué ocurre esto?Más precisamente, ¿por qué una función de puntero que devuelve un puntero a una matriz asignable golpea el primer elemento de esa matriz para la persona que llama?Más precisamente aún, ¿por qué apuntar con un puntero (b) producir un efecto secundario en otro puntero (a), donde los objetivos provienen de diferentes funciones que están escritas para no interactuar entre sí en absoluto?

Advertencias

Obtengo este comportamiento usando el compilador GNU Fortran v.4.3.3, ejecutando una computadora portátil Intel con Ubuntu (Jaunty).Sus resultados pueden variar, lo que podría ser aún más interesante.Finalmente, como siempre, podría ser un error del operador por mi parte, lo cual al menos sería interesante para mí.

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
¿Fue útil?

Solución

Variable array de function1 es una variable local - porque se ha declarado sin el "Guardar" atributo, no es persistente y no está definida cuando se cierra la función. Se asigna la dirección de array a function1, "mantener" esta dirección, pero la dirección no es significativa una vez que la variable se convierte en indefinido después de salir de la función. Una aplicación posible es que array de function1 se colocará en la pila, y esa zona de la pila será liberado para otros usos cuando se devuelve FUNCTION1. Pero esto es sólo una conjetura en una implementación probable - el punto clave es que usted no está autorizado a utilizar el valor del puntero después de la variable se convierte en indefinido. las variables asignables se cancela la asignación automática cuando salen del ámbito menos que se declaran con la opción "Guardar" atributo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top