1

语境

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

这就是我觉得奇怪的地方。

  1. 如果我指向a的结果function1,则结果不正确。的第一个元素a似乎被“破坏”了: ahas 0, 2, 3.
  2. 如果我指向b的结果function2,则结果是正确的。 b得到1, 2, 3.
  3. 更奇怪的是,指向改变后b结果,使其变得正确。 然后有, , .function2 afunction1 aa123

问题

为什么会出现这种情况?更准确地说,为什么返回指向可分配数组的指针的指针函数会为调用者破坏该数组的第一个元素?更准确地说,为什么指向一个指针 ( b) 会对另一个指针 ( ) 产生副作用a,其中目标来自不同的函数,这些函数被编写为根本不相互交互?

注意事项

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

代码

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
4

1 回答 1

4

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

于 2009-10-17T02:10:54.840 回答