从Fortran 90中的指针别名释放指针目标

ale*_*xis 3 fortran pointers memory-management

代码

program asd

real,pointer        :: a,b,c

allocate(a)
a=2.0
b=>a
c=>a
deallocate(b) !
print *, associated(c,target=a) ! T

end program
Run Code Online (Sandbox Code Playgroud)

用intel编译器返回T. 我得出结论,"b"不是"a"的完全别名,因为我不能解除"a"取"b".所以我的问题是:如果我构造一个指针

function ptr
  real,pointer   :: var,ptr
  allocate(var)
  ptr=>var
end function
Run Code Online (Sandbox Code Playgroud)

可以在调用此函数后解除分配var吗?

非常感谢-

tpg*_*114 7

标准说(第6.3.3.2节):

...释放指针目标会导致与目标或目标的一部分相关联的任何其他指针的指针关联状态变为未定义.

此外,在第16.4.2.1节中,它说:

指针可以具有关联,解除关联或未定义的指针关联状态.

并在注释16.3中指出:

可以通过使用关联在子程序中访问来自模块程序单元的指针.除非保存这些目标,否则此类指针的生命周期大于子程序中声明的目标.因此,如果这样的指针与本地目标相关联,则当子程序定义的过程完成执行时,目标将停止存在,使指针"悬空".本标准认为此类指针具有未定义的关联状态.它们既不相关也不相关.在重新建立状态之前,不得再次使用它们.处理器不需要能够检测指针目标何时不再存在.

所有这一切都是说,.TRUE.您获得的英特尔的结果是特定于编译器的,因为c它具有未定义的关联状态,编译器可以以任何方式报告它们.如果您尝试访问ac,你会得到一个内存错误(或者即使它的工作原理,它是不确定的,并不能保证).

同样,您的示例函数同样危险,因为var当函数返回时无法保证将存在,这意味着ptr函数结果再次未定义.所以,如果你试图var通过结果访问ptr,你将再次得到内存错误.

如果您希望您的功能正常工作,则需要看起来像:

function ptr
  real, pointer, save :: var
  real,pointer   :: ptr
  allocate(var)
  ptr=>var
end function
Run Code Online (Sandbox Code Playgroud)

当然,这引出了最终的问题 - 为什么ALLOCATE指针?使用ALLOCATABLE目标并给它TARGET属性更安全.