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

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

问题描述

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

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. 如果我将a 指向function1 的结果,则结果不正确.a 的第一个元素似乎被破坏"了:a023.
  2. 如果我将b指向function2的结果,结果是正确的.b 得到 123.
  3. 更奇怪的是,将b指向function2的结果指向afunction1 changes a 使其正确.a 则有 123.
  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.

问题

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

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?

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

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.

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"属性声明它们.

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天全站免登陆