String 返回已分配字符串导致内存泄漏

String 返回已分配字符串导致内存泄漏,string,function,memory-leaks,fortran,String,Function,Memory Leaks,Fortran,在Fortran中返回变长字符串的建议解决方案来自以下问题: function itoa(i) result(res) character(:),allocatable :: res integer,intent(in) :: i character(range(i)+2) :: tmp write(tmp,'(i0)') i res = trim(tmp) end function 我的理解正确吗,这个函数的结果永远不会被释放?因此,对于大号码

在Fortran中返回变长字符串的建议解决方案来自以下问题:

  function itoa(i) result(res)
    character(:),allocatable :: res
    integer,intent(in) :: i
    character(range(i)+2) :: tmp
    write(tmp,'(i0)') i
    res = trim(tmp)
  end function
我的理解正确吗,这个函数的结果永远不会被释放?因此,对于大号码和大量呼叫,您可能会遇到内存泄漏

所以我的意思是,在这种情况下,我不指定函数的结果,而是像中一样“就地”使用它

我显然没有提到我可以调用
deallocate
的结果,而当我循环时,它肯定不会超出范围


如果我正确地理解您(@Francescalus),我仍然可以相信它被释放的事实。

如果您的代码从未释放它,或者更相关的是,如果它从未超出范围,您认为结果从未释放是正确的。但是,只有当您丢失对已分配内存的最后一个引用时,才会发生内存泄漏,在现代Fortran中,这实际上是很难做到的,尤其是对于可分配变量,但使用指针会稍微容易一些


如果在另一个例程的范围内分配变量,则当例程完成时,操作系统将获得该变量(“因为Fortran标准规定必须这样做”)。如果它在程序范围内并且从未解除分配,则它不是内存泄漏。

这个问题是一个特定的问题,但具体来说,它允许我们更加精确。你应该阅读那边的答案来了解更多的细节

在正确的实现中不应出现内存泄漏。Fortran标准明确说明了这些结果。例如,在Fortran 2008中,注释12.41表示:

函数结果类似于函数子程序本地的任何其他实体(变量或过程指针)。它的存在开始于函数的执行被启动时,结束于函数的执行被终止时。但是,由于该实体的最终值随后将用于调用函数的表达式的求值,因此实现可能希望推迟释放该实体占用的存储,直到其值已用于表达式求值

当可分配函数结果的存在结束时,它将被解除分配。这适用于所有可分配的结果,而不仅仅是延迟长度字符串


因此,内存可能会“泄漏”一段时间,但我们应该期望可以相当迅速地进行回收。许多级别的函数求值可能会导致问题,但在此之前您可能已经得到了令人讨厌的代码。

在本例中使用:
write
语句完成后,不再需要该值。(甚至在创建了连接的临时函数之后)但是对于循环的每个迭代,我们都有不同的函数结果。
do i = 1, n
    write(*, *) "tmp_"//itoa(i)
end do