Fortran 在函数中增加动态数组大小 [英] Fortran increase dynamic array size in function

查看:26
本文介绍了Fortran 在函数中增加动态数组大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一个 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屋!

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