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

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

问题描述

在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的编译器 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现已解除分配


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增加函数中的动态数组大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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