与c_f_pointer是否fortran数组是否就地整形 [英] with c_f_pointer is fortran array reshape in-place or not

查看:275
本文介绍了与c_f_pointer是否fortran数组是否就地整形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个问题与几年前在

I have a question related to one asked some years ago on Intel Developer Forum about the in-place reshaping of an array.

简而言之,答案是可以分配一个特定等级的数组,并创建一个指向相同内存位置(即就地)但具有不同等级的指针,例如:

In short, the answer was that an array of a certain rank can be allocated, and a pointer created that refers to the same memory location (i.e. in-place), but with a different rank, e.g.:

use, intrinsic :: ISO_C_BINDING
integer, allocatable, target :: rank1_array(:)
integer, pointer :: rank3_array(:,:,:)
integer :: i

! Allocate rank1_array 
allocate(rank1_array(24))

! Created rank3_pointer to rank1_array
call C_F_POINTER (C_LOC(rank1_array), rank3_array, [3,2,4])

! Now rank3_array is the same data as rank1_array, but a 3-dimension array with bounds (3,2,4)

现在我的问题是,如果我deallocate原始数组rank1_array,为什么指针rank3_array仍然是关联的,并且可以毫无问题地使用(貌似).因此,如果我从上面添加代码段:

My question is now that if I deallocate the original array rank1_array, why is it that the pointer rank3_array is still associated, and can be used without a problem (seemingly). Thus, if I append the code segment from above with:

! initialise the allocated array
rank1_array = [(i, i=1,24)]

! then deallocate it
deallocate(rank1_array)

! now do stuff with the pointer
print *, associated(rank3_array)
rank3_array(2,2,1) = 99
print *, rank3_array

编译并运行该程序会给我输出

Compiling and running this program gives me the output

gfortran -Wall my_reshape.f90 -o my_reshape
./my_reshape
T
1 2 3 4 99 6 7 ... 23 24

如果rank1_array的内存已被释放,为什么rank3_array仍然起作用,除非它是原始副本.最初的重塑是否就位?如果有人可以向我解释这种行为,将不胜感激.

If the memory of rank1_array was deallocated, why does rank3_array still function unless it is a copy of the original? Was the initial reshape then in-place or not? Would be very grateful if someone could explain this behaviour to me.

我正在使用其中的gfortran 6.1.0.

I'm using gfortran 6.1.0 of that is of interest.

编辑/更新:

正如@francescalus接受的答案所表明的那样,这里的真正问题是我(不正确!)如何一般地处理指针,而不是特别地使用C_F_POINTER进行就地整形.我看到的奇怪行为只是由于我编写的不兼容的fortran代码而导致的未定义行为的结果.根据@francescalus的答案和评论,我在网上进行了更多阅读,并认为链接到

As the accepted answer by @francescalus indicates, the real issue here is how I (incorrectly!) handled pointers in general and not the in-place reshape with C_F_POINTER in particular. The strange behaviour I saw was just a result of undefined behaviour due to non-compliant fortran code I wrote. Based on @francescalus answer and comments, I did more reading online and thought it might be useful to give a link to a relevant section of a Fortran Reference Manual that very clearly explains how pointers and allocatable arrays should be handled.

推荐答案

使用c_f_pointer代替普通"指针分配与问题无关,而且形状也不更改.

That c_f_pointer is used instead of "normal" pointer assignment is not relevant to the problem, nor is the changing shape.

在调用c_f_pointer之后,指针rank3_array是与目标rank1_array关联的指针.没有副本.

After the call to c_f_pointer the pointer rank3_array is pointer associated with the target rank1_array. There is no copy made.

在语句中取消分配rank1_array

 deallocate(rank1_array)

这对以rank1_array为目标的指针有影响.特别是,rank3_array的指针关联状态变为未定义. (只要通过指针释放了指针的目标,指针的关联状态就变得不确定.)

this has an effect on the pointer which has rank1_array as a target. In particular, the pointer association status of rank3_array becomes undefined. (Whenever a pointer's target is deallocated except through the pointer, the pointer's association status becomes undefined.)

下一部分具有未定义关联状态的指针

With the pointer of undefined association status the next part

print *, associated(rank3_array)

不允许

.此时,该程序不是与Fortran兼容的程序(并且编译器无需检测到该程序),并且如果需要,可以允许处理器在此处打印.TRUE..

同样,

rank3_array(2,2,1) = 99
print *, rank3_array

rank3_array本身未定义,也不允许这些引用.同样,编译器可以使用任何效果.

rank3_array itself is undefined and those references are also not allowed. Again, any effect is available to the compiler.

现在,例如关于类似主题的另一个答案:仅仅是因为rank1_array已被释放,并不意味着清除内存.可能发生的一切只是第一个数组的某些数组描述符的状态发生了变化.对所有相关的指针/描述符执行相同的操作不是编译器的责任. (因此指针的描述符的确可能仍然说关联".)

Now, as in another answer on a similar topic: just because rank1_array has been deallocated that doesn't mean that the memory gets purged. Probably all that happens is some array descriptor for the first array has its status changed. It isn't the compiler's responsibility to do the same to all related pointers/descriptors. (And so the pointer's descriptor may indeed still say "associated".)

但是,请务必注意:它看起来好像正在运行,但我不建议您将工作押在此上.

It's important to note, though: it may look like it's working, but I wouldn't advise betting your job on it.

这篇关于与c_f_pointer是否fortran数组是否就地整形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆