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

时间:2012-10-16 03:56:01

标签: pointers memory-management fortran

代码

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”的完全别名,因为我不能解除“a”取“b”。 所以我的问题是:如果我用

构造一个指针
function ptr
  real,pointer   :: var,ptr
  allocate(var)
  ptr=>var
end function

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

非常感谢 -

1 个答案:

答案 0 :(得分:7)

The standard说(第6.3.3.2节):

  

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

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

  

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

并在注释16.3中指出:

  

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

所有这一切都是说来自英特尔的.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属性会更安全。