【问题标题】:Deallocate pointer target from a pointer alias in Fortran 90从 Fortran 90 中的指针别名中释放指针目标
【发布时间】:2012-10-16 03:56:01
【问题描述】:

代码

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

使用英特尔编译器返回 T。我得出结论,“b”不是“a”的完整别名,因为我无法释放“a”占用“b”。 所以我的问题是:如果我用

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

调用这个函数后是否可以释放var?

非常感谢-

【问题讨论】:

    标签: pointers memory-management fortran


    【解决方案1】:

    The standard 说(第 6.3.3.2 节):

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

    进一步,在第 16.4.2.1 节中,它说:

    指针的关联状态可能为关联、解除关联或未定义。

    在注释 16.3 中指出:

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

    所有这一切都是说您从英特尔获得的.TRUE. 的结果是特定于编译器的,因为c 具有未定义的关联状态,编译器可以按照他们想要的任何方式报告。如果你尝试通过c 访问a,你会得到一个内存错误(或者即使它有效,它是未定义的并且不能保证)。

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

    如果你想让你的函数工作,它需要看起来像:

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

    当然,这引出了终极问题——为什么是ALLOCATE 指针?将ALLOCATABLE 用作目标并为其赋予TARGET 属性会更安全。

    【讨论】:

    • +1 表示未定义的指针。注意:不久前我们在这里遇到过,可分配结构组件不能有目标属性。
    • 关于为什么要分配指针的注释:我相信这是在派生数据类型中包含动态数组的唯一方法,最高可达 F90/95。
    • 非常感谢您的完美回答!!关于为什么我需要分配指针:我需要两个列表,一个存储数据,另一个只指向它。由于在 fortran 中有类似 c++ 的模板,我发现更容易使用节点内的数据指针并根据需要更改状态。这样我就避免了声明两种列表类型和大量相关的代码行。
    猜你喜欢
    • 2014-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-10
    相关资源
    最近更新 更多