Jel*_*lby 3 fortran dynamic-memory-allocation
假设我有类似的东西:
real, dimension(:), allocatable :: S
integer, dimension(:) :: idx
...
S = S(idx)
Run Code Online (Sandbox Code Playgroud)
whereS和idx在分配之前正确分配/初始化。
Fortran 标准对 的内存位置(地址)有S什么说法(如果有的话)?分配后它应该留在同一个地方吗?是否未指定(由编译器决定)?是否有所作为,如果S不是allocatable?
完整示例:
$ cat test.f90
program test
implicit none
real, dimension(:), allocatable :: S
integer :: i, idx(7) = [1,3,5,7,2,4,6]
allocate(S(size(idx)))
do i=1,size(S)
S(i) = i*i
end do
write(6,*) S
write(6,*) loc(S)
S = S(idx)
write(6,*) S
write(6,*) loc(S)
S(:) = S(idx)
write(6,*) S
write(6,*) loc(S)
deallocate(S)
end program
$ sunf90 -V
f90: Studio 12.6 Fortran 95 8.8 Linux_i386 2017/05/30
$ sunf90 test.f90 ; ./a.out
1.0 4.0 9.0 16.0 25.0 36.0 49.0
37518752
1.0 9.0 25.0 49.0 4.0 16.0 36.0
37519840
1.0 25.0 4.0 36.0 9.0 49.0 16.0
37519840
Run Code Online (Sandbox Code Playgroud)
(假设loc给出与数组地址相关的内容)
在您的示例中,是否idx与S. 如果是,则 的形状与 的形状S(idx)相同,S并且标准表示不会S发生重新分配。但是如果它们不同,那么标准说S是释放,然后重新分配到 的形状S(idx)。如果发生这种解除分配/重新分配,如果基地址保持不变,这是不可预测的(并且可能不太可能)。
然后你问如果S不可分配怎么办- 在这种情况下,形状必须匹配并且它只是数据的副本,尽管可能通过临时数组,因为存在重叠。
-- 编辑 2019 年 8 月 24 日 --
我对此进行了调查 J3(美国 Fortran 标准委员会)电子邮件列表。共识是,在没有 的情况下TARGET,“更改地址”是符合标准的,尽管不止一位成员质疑这是否是一个好主意。编译器开发人员显然认为分配新存储并执行单个副本比保留相同存储并执行两个副本(一个到临时,然后一个返回到S.)更快。如果有大量数据,我可能会认为这是有益的复制 - 也许 - 但不是在较小的情况下。
在任何情况下,你可以,因为你发现,通过给禁用此行为S的TARGET属性。