例如,我想要一个函数来计算两个矩阵的换向器。我实现它的方式是这样的:
function commutator_dd(MA,MB)
> result(MC)
implicit none
real*8,intent(in) :: MA(:,:)
real*8,intent(in) :: MB(:,:)
real*8,allocatable :: MC(:,:)
real*8,allocatable :: MP(:,:),MN(:,:)
integer :: nn
nn=size(MA,1)
allocate(MC(nn,nn),MP(nn,nn),MN(nn,nn))
MP=MATMUL(MA,MB)
MN=MATMUL(MB,MA)
MC=MP-MN
return;end function
我的一位朋友指出,也许分配阵列而不是解除分配它们并不是一个好主意。我倾向于同意这一点,但因为它是我在返回main之前无法释放MC(我认为fortran在退出程序后会自动解除分配,但我记得留下这样的东西并不是一个好习惯)。他建议给nn作为函数的输入并将所有矩阵声明为M(nn,nn)而不是使用分配(或者至少使用MC),但我有点不喜欢添加不必要的输入。
其他可能性是声明MC(大小(MA,1),大小(MA,1)),但我之前遇到过这种语法问题(我无法确定问题究竟是什么,因为通过使用传递变量的不同方法来绕过它总是更容易,但我记得在尝试这样做的时候从编译器得到抱怨。)
哪种方法最好?内在程序(如matmul)处理这个问题的方式是什么? (我尝试谷歌搜索matmul的代码,但我发现的确不像我期望的那样简单。)
答案 0 :(得分:1)
我,我只是使用自动数组作为回报,就像这样
function commutator_dd(MA,MB) result(MC)
implicit none
real*8,intent(in) :: MA(:,:)
real*8,intent(in) :: MB(:,:)
real*8 :: MC(size(ma,1),size(ma,2))
MC=MATMUL(MA,MB)-MATMUL(MB,MA)
return
end function
让编译器根据需要创建临时文件。像你一样,我认为没有必要(不是因为关于Fortran 90)在参数列表中包含输入数组的维度。当然,如果输入数组不符合要求,则此代码段不会进行错误检查并且会失败。
如果您的编译器确实抱怨MC
报告的自动调整大小;我看不出它应该有什么理由。
答案 1 :(得分:1)
自动数组(我不确定它是函数结果的正确标准术语)@HighPerformanceMark建议这里是最好的设计选择,但你甚至不用担心可分配的数组。
在现代Fortran中,任何内存泄漏都是不可能的,allocatable
是标量或数组,无论是变量还是派生类型组件,无论如何。内存始终保证自动释放,除非它具有save属性(通常用于此目的)。
在您的情况下,可分配的函数结果由调用代码自动释放,而临时数组在子例程完成时自动释放。
另请注意,在Fortran 2003(无论如何都需要可分配函数结果)中,您可以省略allocate
语句。数组将在=
分配期间自动分配。
摘要:对于任何deallocate()
,您很少需要allocatable
。您经常对pointer
个变量使用它。关于什么是最佳实践 - 当标准保证正确的行为时,为什么用不必要的语句使代码混乱?