代码

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

用intel编译器返回T。我得出的结论是,“b”不是“a”的完整别名,因为我无法使用“b”来释放“a”。
所以我的问题是:如果我用
function ptr
  real,pointer   :: var,ptr
  allocate(var)
  ptr=>var
end function

是否可以在调用此函数后取消分配var?

非常感谢-

最佳答案

The standard说(第6.3.3.2节):

...取消分配指针目标会导致指针关联状态为
与目标或目标的一部分相关联的任何其他指针将变得不确定。

进一步,在16.4.2.1节中说:

指针的状态可能是已关联,已取消关联或未定义。

在注释16.3中指出:

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

这就是说,您从Intel获得的.TRUE.的结果是特定于编译器的,因为c具有未定义的关联状态,编译器可以按他们想要的任何方式报告该状态。如果您尝试通过a访问c,则会收到内存错误(或者即使它起作用,它也是未定义的,而不是保证的)。

同样,示例函数同样具有危险性,因为不能保证函数返回时var就会存在,这意味着ptr函数的结果再次未定义。同样,如果您尝试通过var的结果访问ptr,您将再次遇到内存错误。

如果您希望函数正常工作,则需要如下所示:

function ptr
  real, pointer, save :: var
  real,pointer   :: ptr
  allocate(var)
  ptr=>var
end function

当然,这引出了最终的问题-为什么使用ALLOCATE指针?将ALLOCATABLE用作目标,并为其指定TARGET属性,这要安全得多。

10-08 05:27
查看更多