【问题标题】:Automatic array deallocation in FortranFortran 中的自动数组解除分配
【发布时间】:2014-02-28 08:28:29
【问题描述】:

我正在使用 gfortran -std=f2008。我有一个函数,它返回包含可分配数组的派生类型。该函数在返回之前调用 allocate()。在分配数组的函数返回并且我的程序段错误之后,似乎数组正在自动释放一段时间。

自动解除分配何时发生?我应该以不同的方式对此进行编码吗?

【问题讨论】:

  • 你一定要展示实际的代码。
  • 我会,但我现在没有足够小的测试用例来发布。

标签: fortran


【解决方案1】:

一个通用的答案:可分配数组在超出范围时会自动释放。在外部范围内“使用”结果后,函数结果会自动释放。当父派生类型变量超出范围或被释放时,可分配组件被释放。

只有pointers,指向函数的结果在释放后未定义,不应使用。如果这样做,可能会导致您描述的问题。

此外,当数组在赋值时自动重新分配时,指向它的指针变得未定义(但实际上可能不会改变)。

换句话说,如果正确使用可分配对象,则不会出现您描述的问题。

【讨论】:

  • 那么,如果我持有对函数返回的派生类型的非指针引用,并且具有allocatable 数组组件,那么该数组将保持分配状态吗?
  • 什么是“非庞特”参考?您究竟希望它何时保持分配状态?整个函数结果(包括非指针组件)在函数值用于表达式或赋值后被释放。
【解决方案2】:

另一个一般建议:大多数时候,使用子例程而不是函数来返回复杂的结果(如数组、指针、内部可分配的派生类型)更安全...

附加问题:您是否在表达式中使用您的函数?如果不是,那么它应该是一个子程序。 Fortran 函数只有在计算表达式中使用时才有意义。

【讨论】:

  • 你能证明你在这个答案中所做的断言是正确的吗?子程序在哪些方面比函数更安全?我挑战你说明一个不在表达式中的函数的使用
  • 因为以子程序为例,返回值通常是在调用程序中明确标识的参数。您不依赖于无法轻松管理的函数结果。关于不在有趣表达式中的函数:a=f(...)。如果仅以这种方式使用该函数,我建议改为“CALL f(...,a)”。
  • 返回指针的函数特别危险。您打算将它与 a=>f(...) 或 a=f(...) 一起使用吗?我已经看到了很多错误。如果函数返回一个数组也是如此。想象一下 a=>f(...) 的结果。
  • @bdforbes 根据语言规则 - 不。就等效 实现而言——也许,如果编译器非常很聪明,并且不可能定义赋值和终结器之类的东西。 F2003 编译器并不多。甚至更少非常智能的 F2003 编译器 :(。但我仍然一直使用具有可分配或派生类型结果的函数(不是指针函数)。
  • @HighPerformanceMark 这是对您的挑战的一个可能晦涩难懂的回应——截至 F2008 勘误表三(很快?),variable 可以是 function-reference i> 返回数据指针结果。变量可以出现在表达式不能出现的许多地方——特别是赋值语句的左侧和读取语句的输入列表中。 (在勘误表三之前,变量的语法规则更加通用,但这会导致语言语法歧义。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-21
  • 2017-07-19
相关资源
最近更新 更多