如何在Fortran中即时增加数组大小?

时间:2011-12-05 11:11:08

标签: arrays fortran fortran90 dynamic-arrays

我的程序正在运行3D数组,标记它找到的“集群”,然后进行一些检查以查看是否有任何相邻集群的标签高于当前集群。还有第二个数组保存了“正确的”群集标签。如果它发现正确标记了第n个相邻簇,则将该元素分配给0,否则将其分配给正确的标签(例如,如果第n个站点具有标签2,并且邻居标记为3,则第3个元素为labelArray设置为2)。我有充分的理由这样做,老实说!

我想要的就是能够动态分配labelArray的第n个元素。我已经查看了可分配数组并将事物声明为labelArray(*),但我并不理解这些,尽管在网上搜索和StackOverflow。

所以这样做的任何帮助都会很棒。

3 个答案:

答案 0 :(得分:9)

这是一个Stack Overflow问题,其中一些代码示例显示了使用Fortran可分配数组的几种方法:How to get priorly-unkown array as the output of a function in Fortran:声明,分配,测试已经被分配,使用新的move_alloc和赋值分配。未显示有显式释放,因为示例在退出过程时使用move_alloc和自动释放。

P.S。如果要重复添加一个元素,则应考虑数据结构方法。通过增长数组一次添加一个元素不是一种有效的方法。在Fortran中将数组从N个元素增长到N + 1可能意味着创建一个新数组并复制所有现有元素。更合适的数据结构可能是链表。您可以通过创建用户定义的类型并使用指针在Fortran中创建链接列表。你将成员链接在一起,指向一个成员。添加其他成员的开销很小。缺点是最容易按顺序访问列表成员。使用索引,您无法轻松地以任何顺序访问成员。

我在网络上找到的有关Fortran链接列表的信息:http://www-uxsup.csx.cam.ac.uk/courses/Fortran/paper_12.pdfhttp://www.iag.uni-stuttgart.de/IAG/institut/abteilungen/numerik/images/4/4c/Pointer_Introduction.pdf

答案 1 :(得分:5)

如果声明一个数组可分配,则使用形式为真实的deffered shape

allocatable :: labelArray(:,:)

,或

real,dimension(:,:),allocatable :: labelArray

双冒号数意味着数组的排名(索引数)。

如果数组未分配,请使用

 allocate(labelarray(shapeyouwant))

具有正确数量的索引。例如allocate(labelarray(2:3,-1:5))对于数组,在demension 1中索引为2到3,在维度2中为-1到5。

要更改尺寸,您必须先使用

取消分配数组
deallocate(labelArray)

要将已分配的数组重新分配给新形状,首先需要使用新形状分配新数组,将现有数组复制到新数组,然后使用{{1}将旧数组的引用移动到新数组}。

move_alloc()

当新数组引用移动 call allocate(tmp(size_old+n_enlarge)) tmp(1:size_old) = array(1:size_old) call move_alloc(tmp, array) 时,旧数组将自动释放。


Fortran 95会自动释放数组,如果它们超出范围(例如,子程序结束)。

Fortran 2008有一个很好的自动分配功能。如果您说move_alloc()并且未分配array1,则会自动分配它以具有正确的形状。

答案 2 :(得分:1)

延迟评论...查看Fortran 90的Numerical Recipes。他们实现了一个很好的重新分配功能,符合Fortran 90标准。在这种情况下,您的数组必须是指针,而不是可分配的属性。

该函数接收旧数组和所需大小,并返回指向新调整大小的数组的指针。

如果可能的话,使用Fortran 95或2003.如果2003不可能,那么95就是一个很好的折衷方案。它提供了更好的指针语法。