Fortran 在函数中增加动态数组大小

标签 fortran

我需要一个 Fortran 中的可变大小数组。在 C++ 中,我会使用向量。所以我有一个像

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

如果我这样使用它就可以正常工作
integer pos, val
pos = append(n, array, val)

但是,如果我想以这种方式使用它
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) 的地址时,地址空间已被释放。

我想要的是将 array(j) 的值放在堆栈上(不是地址),然后在函数中使用,在函数完成后,查找 array(i) 的最新地址并得到结果函数保存到它。

我很确定 gcc 会按照我想要的方式来做,为什么 gfortran 如此刻薄?

Fortran 中是否有任何方法可以实现健壮(意味着 array(j) = ... 示例有效)
函数或数据类型具有类似行为的 c++ STL 向量?

结论:

我最终引入了临时变量
integer tmp_val
tmp_val = value
...
array(n) = tmp_val

所以至少该方法可以被称为
pos = append(n, array, array(j))
array(i) = pos

并希望该项目的其他/ future 开发人员不要试图“优化”这两行以消除“pos”的必要性。

感谢您的回答和评论。

最佳答案

IRO-bot 的答案是 Fortran 90 的正确方法。如果您可以限制自己使用支持 Fortran 2003 的编译器 MOVE_ALLOC内在(自 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 is now deallocated

关于Fortran 在函数中增加动态数组大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7523228/

相关文章:

数组和派生类型

快速计算R中的二重积分

module - Fortran 模块中类型之间的循环依赖

pointers - 第 0 个索引处的指针有问题

segmentation-fault - Gfortran : Segmentation fault with long character

c - 在 C 中为 fortran 数组分配内存

c++ - 从 C++ 调用带有可选参数的 Fortran 子例程

multithreading - 共享内存计算机上的多线程 FFTW 3.1.2

compiler-errors - 为什么在编译时MinGW无法识别我的目标文件?

performance - 将屏蔽数组添加到另一个 Fortran 的最有效方法