【问题标题】:Fortran dynamic objectsFortran 动态对象
【发布时间】:2012-12-27 23:34:12
【问题描述】:

我正在尝试创建一个以指针形式返回数据的子例程:

我想要这样的东西:

subroutine f(p)
     type(tra), pointer p
     type(tra), target :: instance

     p=>instance
     do_work(instance)
end subroutine

严格来说,我想实现类似 c++ 的“new”操作符。

然后我想使用这样的子程序如下:

subroutine other
    type(tra), pointer :: p1,p2
    call f(p1)
    call f(p2)
end subroutine

上面的代码可能不起作用,因为我认为 f 中的“实例”在 f 退出后被销毁,并且下一次调用 f 在内存中的同一位置再次创建“实例”。

特别是我发现p1p2 指向相同的对象,但我想这是依赖于编译器的。 是真的吗?

我认为一个可能的解决方案是:

subroutine f(p)
     type(tra), pointer p
     type(tra), allocatable, target :: instance(:)

     p=>instance(1)
     do_work(instance(1))
end subroutine

这是“官方”的做事方式吗?

【问题讨论】:

  • 数据必须作为指针返回是否有特殊原因?在没有这种特殊原因的情况下,现代 Fortran (F2003+) 中更好的方法是使参数 ALLOCATABLE。

标签: memory-management fortran


【解决方案1】:

严格来说,我想实现类似 c++ 的“new”操作符。

它是ALLOCATE。你想要做的事情应该是这样的:

subroutine f(p)
     type(tra), pointer :: p

     ! you can actually leak memory this way! caution required.
     if(associated(p)) then
         stop "possible memory leak - p was associated"
     end
     allocate(p)
     do_work(p)
end subroutine

上面的代码可能不起作用,因为我认为 f 中的“实例”在 f 退出后被销毁,并且下一次调用 f 在内存中的同一位置再次创建“实例”。

不,这不是真的。局部子程序变量通常被“分配”一次(甚至只初始化一次),参见例如Fortran 90 规范,第 14 章,尤其是第 14.7 节。

【讨论】:

  • 在您的示例中,当调用 ASSOCIATED 内在函数时, p 的指针关联状态未定义。使用这样的指针调用ASSOCIATED 是违反语言规则的。示例中p 的类型声明语句缺少双冒号。对do_work 的调用将instance 作为实际参数——应该是p 吗? OP 在他们的第一个示例代码中关于instance 的生命周期的假设在它出现的上下文中是正确的。
  • @IanH,我修正了代码中明显的拼写错误。关于子程序参数的关联状态,您确实是对的,严格来说,如果子程序 f 与未定义的指针一起使用,则这段代码一定不能编译。但是,如果调用者声明了具有初始空关联的相应变量(无论如何强烈推荐),则可以定义此指针。关于局部变量的生命周期,Fortran 标准对没有 save 属性的局部变量没有任何特定的生命周期要求,因此这取决于实现。
  • 也许我看错了。为了清楚起见,OP 所暗示的“可能不起作用”绝对是非法的。当子程序的执行终止时,未保存的局部变量变为未定义(F2003 甚至允许您通过终结来观察某些局部变量的“生命周期结束” - 或多或少相当于 C++ 中的销毁)和指向未保存局部变量的指针当子程序的执行终止时变得未定义。围绕变量存储位置的实现选择可能会隐藏此编程错误,但这仍然是一个错误。
  • 所以“assiciate”代码没问题,修正了错别字,此外,为了确保它不会使传递的指针崩溃,应该声明“子例程 f”:TYPE(tra),POINTER: : VEC => NULL () ??
  • @Lacek,是的,如果传递的指针总是被初始化(定义),associated 位是可以的。无论如何,将 Fortran 指针用于比链表/哈希表更复杂的东西通常太容易出错并且依赖于编译器,通常最好使用可分配数组。
猜你喜欢
  • 2020-02-17
  • 1970-01-01
  • 1970-01-01
  • 2015-05-05
  • 2023-03-11
  • 2011-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多