如何在 Fortran 中动态增加数组大小?

问题描述 投票:0回答:4

我的程序正在运行 3D 数组,标记它找到的“簇”,然后进行一些检查以查看是否有任何相邻簇的标签高于当前簇。还有第二个数组包含“正确的”集群标签。如果它发现第 n 个相邻集群被正确标记,则将该元素分配给 0,否则将其分配给正确的标签(例如,如果第 n 个站点的标签为 2,并且邻居的标签为 3,则该元素的第 3 个元素

labelArray
设置为 2)。老实说,我有充分的理由这样做!

我想要的只是能够动态分配

labelArray
的第n个元素。我看过可分配的数组并将事物声明为
labelArray(*)
但我并不真正理解这些,尽管搜索了网络和StackOverflow。

所以在这方面的任何帮助都会很棒。

arrays fortran fortran90 dynamic-arrays
4个回答
12
投票

这里是一个 Stack Overflow 问题,其中包含一些代码示例,展示了使用 Fortran 可分配数组的几种方法:新的 move_alloc 和分配分配。未显示显式释放,因为示例使用 move_alloc 并在过程退出时自动释放。 附言如果你想重复添加一个元素,你应该考虑你的数据结构方法。通过增长数组一次添加一个元素不是一种有效的方法。要在 Fortran 中将数组从 N 个元素增长到 N+1,可能意味着创建一个新数组并复制所有现有元素。更合适的数据结构可能是链表。您可以通过创建用户定义类型和使用指针在 Fortran 中创建链表。您将成员链接在一起,从一个指向下一个。添加另一个成员的开销很小。缺点是按顺序访问列表的成员最容易。你没有数组的简单能力,使用索引,以任何顺序访问成员。

我在网上找到的有关 Fortran 链表的信息:

http://www-uxsup.csx.cam.ac.uk/courses/Fortran/paper_12.pdf

http://www.iag.uni -stuttgart.de/IAG/institut/abteilungen/numerik/images/4/4c/Pointer_Introduction.pdf


8
投票

allocatable :: labelArray(:,:)


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


双冒号的数量表示数组的等级(索引的数量)。

如果数组未分配你使用

allocate(labelarray(shapeyouwant))

具有正确数量的索引。例如 
allocate(labelarray(2:3,-1:5))

对于维度 1 中索引为 2 到 3 和维度 2 中索引为 -1 到 5 的数组。


要更改维度,您必须先使用

释放数组

deallocate(labelArray)


要将分配的数组重新分配给新形状,您首先需要使用新形状分配一个新数组,将现有数组复制到新数组,然后使用
move_alloc()

将旧数组的引用移动到新数组。


call allocate(tmp(size_old+n_enlarge)) tmp(1:size_old) = array(1:size_old) call move_alloc(tmp, array)

当新数组引用移动
move_alloc()

时,旧数组会自动释放。


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

Fortran 2008 有一个很好的自动分配分配功能。如果你说

array1=array2

并且 array1 没有分配,它会自动分配为具有正确的形状。


它也可以用于重新分配(另见

Fortran array automatically growing when adding a value

How to add new element to dynamic array in Fortran 90 labelArray = [labelArray, new_element]



1
投票

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

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


0
投票

allocate(tmp(size_old+n_enlarge)) tmp(1:size_old) = array(1:size_old) !copy the data call move_alloc(tmp, array) !rename

注意
move_alloc

只涉及复制内部描述符(不是数组中的实际数据),因此指向的存储是相同的。

总而言之,

move_alloc

提供了一种有效的方法来将数组重新分配到更大的大小,而无需复制数据两次(您只需复制一次数据)。也就是说,你需要抄入,但不需要抄出。

    

© www.soinside.com 2019 - 2024. All rights reserved.