【问题标题】:Fortran pointer functions: why does this code's behavior depend on the order of function calls?Fortran 指针函数:为什么此代码的行为取决于函数调用的顺序?
【发布时间】:2010-12-07 12:23:00
【问题描述】:

上下文

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

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

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

问题

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

【问题讨论】:

    标签: pointers fortran gfortran fortran90


    【解决方案1】:
    function1 的

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-01
      • 2018-11-19
      • 2017-01-26
      • 2014-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多