Fortran中的可变大小数组,没有Allocate()

时间:2011-07-07 20:51:25

标签: arrays memory stack heap fortran

有没有办法在堆栈中的Fortran 中创建可变大小的数组? Allocate()对我不起作用,因为它将数组放在堆上。这可能会导致并行化问题(请参阅我的其他问题: OpenMP: poor performance of heap arrays (stack arrays work fine))。当然,一些智能内存管理会解决这个问题,但Fortran中的内存管理听起来很愚蠢。

基本上,我在C中寻找与以下相同的Fortran:

scanf("%d", N);
int myarray[N];

重新迭代:我不想要

Integer, PARAMETER :: N=100
Integer, Dimension(N) :: myarray

因为这确定了编译时的数组大小。我也不想要

Integer, Dimension(:), Allocatable :: myarray
read(*,*) N
Allocate(myarray(1:N))

因为它将数组放在堆上。

非常感谢。在我最近遇到上述问题中的问题之前,我对Allocatable阵列非常满意。如果对这个问题有一个否定的答案,我将非常感谢与该来源的链接。

编辑:请参阅M.S.B.的回答。只有在Fortran 2008中才能实现这种优雅的方式,并且它是在block构造中完成的。

2 个答案:

答案 0 :(得分:11)

Fortran可以自动创建数组,只要在子程序的入口处有声明,只要维度在运行时已知...这不需要声明维度参数属性,它们可以是参数,例如,

subroutine MySub ( N )

integer, intent (in) :: N
real, dimension (N) :: array

有效。那么为什么不在主程序或某个子程序中决定你的大小“N”,然后调用另一个子程序继续。可能这种方法阵列将在堆栈上。正如@eriktous所写,Fortran语言标准没有指定这种行为。有些编译器将本地数组切换到超过一定大小的堆。某些编译器提供了控制此行为的选项。将大型数组放在堆上可能会被递归或OpenMP覆盖。

您还可以将可分配数组作为实际参数传递给子例程,而不将子例程的伪参数声明为可分配。这可能无助于您的关注,因为原始数组仍可能在堆上。

答案 1 :(得分:6)

Fortran标准没有堆栈和堆的概念,因此这将依赖于实现(即编译器)。查看文档,例如gfortran,它有一个选项

-frecursive
    Allow indirect recursion by forcing all local arrays to be allocated on the stack.

其他编译器可能有类似的选项。也许这就是你想要的。