语境

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

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

  1. 如果我指点 a 的结果 function1, ,结果不正确。第一个元素 a 似乎被“破坏”了: a0, 2, 3.
  2. 如果我指点 b 的结果 function2, ,结果是正确的。 b 得到 1, 2, 3.
  3. 还是陌生人指着 b 的结果 function2 指点 afunction1 变化 a 这样它就变得正确了。 a 然后有 1, 2, 3.

问题

为什么会出现这种情况?更准确地说,为什么返回指向可分配数组的指针的指针函数会破坏调用者该数组的第一个元素?更准确地说,为什么指向一个指针(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
有帮助吗?

解决方案

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top