Fortran指针函数:为什么这段代码的行为取决于函数调用的顺序?

时间:2009-10-16 21:05:58

标签: pointers fortran gfortran fortran90

上下文

下面发布的玩具Fortran代码调用两个指针函数。也就是说,两个函数都返回一个指针。实际上,它们都是数组指针。它们都尝试做同样的事情,即返回一个引用具有三个元素1,2和3的整数数组的整数数组指针。第一个函数使用指针赋值运算符(=>)指向函数指针到包含数据的可分配数组。第二个函数通过指针直接分配一块动态存储器,用于存储数据。调用程序只打印返回数组的元素。

这是我觉得奇怪的事情。

  1. 如果我将a指向function1的结果,则结果不正确。 a的第一个元素似乎是“被破坏”:a023
  2. 如果我将b指向function2的结果,则结果是正确的。 b获得123
  3. 陌生人仍然将b指向function2 的结果 a指向function1 更改 a,使其变得正确。 a然后有123
  4. 问题

    为什么会这样?更确切地说,为什么一个指针函数返回一个指向可分配数组的指针,它会破坏调用者的那个数组的第一个元素?更确切地说,为什么指向一个指针(b)会在另一个指针(a)上产生副作用,其中目标来自不同的函数,这些函数是为了不相互交互而编写的一点都没有?

    注意事项

    我使用GNU Fortran编译器v.4.3.3,运行带有Ubuntu(Jaunty)的Intel笔记本电脑。您的结果可能会有所不同,这可能会更有趣。最后,一如既往,我可能是操作员错误,至少对我来说这很有趣。

    代码

    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
    

1 个答案:

答案 0 :(得分:4)

function1的变量数组是一个局部变量 - 因为它是在没有“save”属性的情况下声明的,它不是持久的,并且在函数退出时是未定义的。您将 array 的地址分配给function1,“保留”该地址,但是一旦退出该函数变量未定义,该地址就没有意义。一个可能的实现是,function1的 array 将放在堆栈上,当function1返回时,堆栈的那个区域将被释放用于其他用途。但这只是对可能实现的猜测 - 关键是在变量未定义后不允许使用指针值。可分配变量在超出范围时会自动释放,除非您使用“save”属性声明它们。