Fortran指针函数:为什么此代码的行为取决于函数调用的顺序? [英] Fortran pointer functions: why does this code's behavior depend on the order of function calls?

查看:146
本文介绍了Fortran指针函数:为什么此代码的行为取决于函数调用的顺序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

上下文

下面发布的玩具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)产生副作用,在该指针中,目标来自编写的不同函数,因此根本不会相互影响? /p>

注意事项

我使用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的变量 array 是局部变量-因为声明时没有"save"属性,所以它不是持久的且函数退出时未定义.您将 array 的地址分配给function1,保留"该地址,但是一旦变量从函数退出后变得未定义,该地址就没有意义.一种可能的实现是将function1的 array 放置在堆栈上,并且当function1返回时,该堆栈的区域将被释放以用于其他用途.但这只是对可能的实现方式的猜测-关键点是,在变量变为未定义状态后,不允许您使用指针值.可分配变量超出范围时将自动释放,除非您使用"save"属性声明它们.

Context

The toy Fortran code posted below calls two pointer functions. That is, both functions return a pointer. In fact, they're both array pointers. They both attempt to do the same thing, which is to return an integer array pointer referencing an integer array having three elements, 1, 2, and 3. The first function uses the pointer assignment operator (=>) to point the function pointer to an allocatable array that holds the data. The second function allocates a block of dynamic memory directly, via the pointer, for storing the data. The calling program just prints the elements of the returned array(s).

Here's what I find odd.

  1. If I point a to the result of function1, the results are not correct. The first element of a appears to be "clobbered": a has 0, 2, 3.
  2. If I point b to the result of function2, the results are correct. b gets 1, 2, 3.
  3. Stranger still, pointing b to the result of function2 after pointing a to function1 changes a such that it becomes correct. a then has 1, 2, 3.

Question

Why does this occur? More precisely, why does a pointer function that returns a pointer to an allocatable array clobber the first element of that array for the caller? More precisely still, why does pointing one pointer (b) produce a side-effect on another pointer (a), where the targets come from different functions that are written so as not to interact with each other at all?

Caveats

I get this behavior using the GNU Fortran compiler v.4.3.3, running an Intel laptop with Ubuntu (Jaunty). Your results may vary, which might be more interesting still. Finally, as always it could be operator error on my part, which would be interesting to me at least.

Code

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

解决方案

Variable array of function1 is a local variable -- because it is declared without the "save" attribute, it is not persistent and is undefined when the function exits. You assign the address of array to function1, "keeping" this address, but the address isn't meaningful once the variable becomes undefined after exiting from the function. A likely implementation is that array of function1 will be placed on the stack, and that area of the stack will be freed for other uses when function1 returns. But this is just a guess at a likely implementation -- the key point is that you aren't allowed to use the pointer value after the variable becomes undefined. Allocatable variables are automatically deallocated when they go out of scope unless you declare them with the "save" attribute.

这篇关于Fortran指针函数:为什么此代码的行为取决于函数调用的顺序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆