labelArray
设置为2)。我有一个很好的理由这样做,真的!我想要的只是能够即时分配
labelArray
的第n个元素。我已经查看了可分配数组和声明为labelArray(*)
的内容,但是尽管在网上搜索和StackOverflow上搜索,我仍然不太理解。因此,对于如何做到这一点的任何帮助都将是极好的。
labelArray
设置为2)。我有一个很好的理由这样做,真的!labelArray
的第n个元素。我已经查看了可分配数组和声明为labelArray(*)
的内容,但是尽管在网上搜索和StackOverflow上搜索,我仍然不太理解。以下是一个 Stack Overflow 问题,其中提供了一些代码示例,展示了使用 Fortran 可分配数组的几种方法:How to get priorly-unkown array as the output of a function in 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
allocatable :: labelArray(:,:)
或者
real,dimension(:,:),allocatable :: labelArray
其中双冒号的数量表示数组的秩(索引数)。 allocate(labelarray(shapeyouwant))
确保正确的索引数量。例如,对于索引在第1维从2到3,在第2维从-1到5的数组,请使用allocate(labelarray(2:3,-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 数组添加值时自动增长 和 Fortran 90 动态数组如何添加新元素)
labelArray = [labelArray, new_element]
allocate(labelArray(size(labelArray)+1))
我想要的只是在添加元素时增加大小。 - AncientSwordRage释放
它,重新分配
更大的空间并将保存的值复制回来。如果编译器支持,你可以使用move_alloc
,而不是复制,这样你不必释放你的数组,只需分配更大的空间并将保存的值复制回来即可。 - Vladimir F Героям славаrealloc
函数,但Fortran却没有。 - Vladimir F Героям слава综上所述,增加可分配数组大小的Fortran最先进的方法如下:
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
提供了一种有效的方式来重新分配更大尺寸的数组,而无需复制两次数据(只需要复制一次数据)。也就是说,您需要进行复制,但不需要进行复制输出。
allocate(temp(size(labelArray)+1))// temp(:size(labelArray))=labelArray// call move_alloc(temp,labelArray)
- AncientSwordRagedeallocate(labelArray)
。你有什么想法吗? - AncientSwordRage