Fortran 在函数中增加动态数组大小 [英] Fortran increase dynamic array size in function
问题描述
我需要一个 Fortran 中的可变大小数组.在 C++ 中,我会使用向量.所以我有一个类似
I need a variable size array in Fortran. In C++ I would use vector. So I have a function like
integer function append(n, array, value)
integer, pointer, dimension(:) :: array
integer, pointer, dimension(:) :: tmp_arr
integer n
if (size(array) .eq. n) then
allocate(tmp_arr(2*size(array)))
tmp_arr(1:size(array)) = array
deallocate(array)
array => tmp_arr
end if
n = n + 1
array(n) = value
append = n
end function
如果我这样使用它会很好用
that works fine if I use it the way
integer pos, val
pos = append(n, array, val)
但是,如果我想以这种方式使用它
However, if I would like to use it the way
integer i,j,n ! i,j<n
array(i) = append(n, array, array(j))
使用 gfortran 这不起作用.它编译,但段错误.问题似乎是gfortran从array(i)和array(j)中生成地址,将后者发送到函数append,然后当array(j)的地址被访问并且array(i)的地址被写入时,地址空间已被释放.
with gfortran this does not work. It compiles, but segfaults. The problem seems to be that gfortran makes addresses out of array(i) and array(j), sends the latter to the function append, and then when the address of array(j) is accessed and the one of array(i) written, the address space has been deallocated.
我想要的是数组(j)的值被放入堆栈(而不是地址),然后在函数中使用,在函数完成后查找数组(i)的最新地址并函数的结果保存到它.
What I would like is that the value of array(j) is put on the stack (not the address) and then used in the function and after the function has finished the uptodate address of array(i) is looked up and the result of the function saved to it.
我很确定 gcc 会按照我想要的方式做,为什么 gfortran 如此卑鄙?
I am pretty sure gcc would do it the way I want, why is gfortran so mean?
在 Fortran 中有什么方法可以使一个健壮的(意味着 array(j) = ... 示例有效)具有类似 c++ stl 向量的行为的函数或数据类型?
Is there any way in Fortran to make a robust (meaning the array(j) = ... example works) function or data type to have a c++ stl vector like behaviour?
结论:
我最终引入了临时变量
integer tmp_val
tmp_val = value
...
array(n) = tmp_val
所以至少该方法可以称为
so at least the method can be called as
pos = append(n, array, array(j))
array(i) = pos
并希望项目中的其他/未来开发人员不会尝试优化"这两条线以消除pos"的必要性.
and hope that other/future developers on the project won't try to 'optimize' the two lines to eliminate the necessity of 'pos'.
感谢您的回答和评论.
推荐答案
IRO-bot 的答案是 Fortran 90 的正确方法.如果你可以限制自己使用支持 Fortran 2003 的编译器 MOVE_ALLOC 内在(自 4.2 版本起包含在 gfortran 中),您可以避免其中一个副本.也就是说,将数组的大小增加 2 倍可以写成
The answer by IRO-bot is the correct approach for Fortran 90. If you can limit yourself to compilers that support the Fortran 2003 MOVE_ALLOC intrinsic (included in gfortran since the 4.2 release), you can avoid one of the copies. That is, increasing the size of an array by a factor of 2 can be written as
allocate(tmp_arr(2*size(array)))
tmp_arr(1:size(array)) = array
deallocate(array)
move_alloc(tmp_arr, array)
! tmp_arr is now deallocated
这篇关于Fortran 在函数中增加动态数组大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!