问题描述
在Fortran中我需要一个可变大小的数组。在C ++中,我会使用向量。所以我有一个函数如$ b $ pre $ $ $ $ $ $ $ $ $ $ $ $整数函数append(n,数组,值)$ b $整数,指针,尺寸:) ::数组
整数,指针,维(:) :: tmp_arr
整数n
if(size(array).eq。n)then
allocate(tmp_arr(2 * size(array)))
tmp_arr(1:size(array))= array
deallocate(array)
array => tmp_arr
结束如果
n = n + 1
array(n)= value
append = n
结束函数
如果我以这种方式使用它,那很好用
整数pos,val
pos = append(n,数组,val)
然而,如果我想用它的方式
整数i,j,n! i,j array(i)= append(n,array,array(j))
用gfortran这不起作用。它编译,但段错误。问题似乎是,gfortran将地址从数组(i)和数组(j)中取出,将后者发送给函数append,然后在访问数组(j)的地址时写入数组(i)中的一个,地址空间已被释放。
我想将数组(j)的值放在堆栈上(而不是地址),然后用于该函数和函数完成后,数组(i)的最高地址被查找,并将函数的结果保存到它。
我很确定gcc会按照我想要的方式来做,为什么gfortran如此意味着什么?
在Fortran中有没有什么办法可以使得健壮(意味着数组(j)= ...示例)
$函数或数据类型具有类似行为的c ++ stl向量吗?
integer tmp_val
tmp_val = value
...
array(n)= tmp_val
so至少该方法可以称为
$ $ p $ $ $ $ $ $ $ $ $ pos $ append(n,array,array(j))
array (i)= pos
并希望项目中的其他/未来开发人员不会尝试优化'两条线,以消除'pos'的必要性。
感谢您的回答和评论。
IRO-bot的答案是Fortran 90的正确方法。如果您可以将自己限制为支持Fortran 2003的编译器内在(自4.2版本以来包含在gfortran中),您可以避免其中一个副本。也就是说,将一个数组的大小增加2倍可以写成:
$ $ $ $ $ $ $ $
allocate(tmp_arr( 2 * size(array)))
tmp_arr(1:size(array))= array
deallocate(array)
move_alloc(tmp_arr,array)
! tmp_arr现已解除分配
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))
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.
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.
I am pretty sure gcc would do it the way I want, why is gfortran so mean?
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?
Conclusion:
I eventually introduced temporary variables
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
and hope that other/future developers on the project won't try to 'optimize' the two lines to eliminate the necessity of 'pos'.
Thanks for the answers and comments.
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增加函数中的动态数组大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!