Arrays Fortran 95-在模块之间传输数组

Arrays Fortran 95-在模块之间传输数组,arrays,fortran,fortran95,Arrays,Fortran,Fortran95,我在模块和主程序之间传输阵列时遇到问题。模块和主程序使用gfortran编译得非常好。但是,在执行.exe文件时,windows遇到问题,必须关闭。只有当数组的大小未知(并且必须分配其大小)时,才会出现这种情况。我已经包含了一小段代码来说明这个问题: 工作原理: 用户被要求输入一个定义方阵大小的整数“i”。该整数被传递给模块函数,模块函数创建矩阵并将其返回给主程序。然后将矩阵打印到屏幕上 一个文件中的主程序: program main1 use module1 implicit none int

我在模块和主程序之间传输阵列时遇到问题。模块和主程序使用gfortran编译得非常好。但是,在执行.exe文件时,windows遇到问题,必须关闭。只有当数组的大小未知(并且必须分配其大小)时,才会出现这种情况。我已经包含了一小段代码来说明这个问题:

工作原理: 用户被要求输入一个定义方阵大小的整数“i”。该整数被传递给模块函数,模块函数创建矩阵并将其返回给主程序。然后将矩阵打印到屏幕上

一个文件中的主程序:

program main1
use module1
implicit none
integer :: i
real,allocatable :: a(:,:)

write(*,*)'Input the size of the square matrix'
read(*,*)i

allocate(a(i,i))
a = function1(i)

write(*,*) 'The square matrix a='
write(*,*) a

deallocate(a)
end program main1
并将模块保存在单独的文件中:

module module1

contains 
function function1(i)
real, allocatable,dimension(:,:) :: function1
integer :: i  

allocate(function1(i,i))
function1 = 1.0

deallocate(function1)
end function function1
end module 

谢谢你们的帮助,伙计们

在函数返回主程序之前,您正在解除分配
函数1
数组。消除
deallocate(function1)
行,它就能正常工作

如果你想要一个方阵的输出,那就不太完美了。您应该将write语句设置为

  do j=1,i
     write(*,*) a(:,j)
  enddo
将输出设置为

  1.000  1.000  1.000
  1.000  1.000  1.000
  1.000  1.000  1.000

请注意,如果您担心
function1
占用内存空间,请编写一个子例程来释放它,并在设置
a=function1(i)

@Kyle的回答指出了导致程序崩溃的问题。但是,您的代码还有一个微妙的问题,您应该注意到,尽管它不完全是一个bug

如果您有一个最新的编译器,并且设置了正确的选项,那么调用代码中的分配语句是不必要的。也就是说,在调用
function1
之前,您不需要分配变量
a
,Fortran将自动将
a
分配给
function1
返回的任何值的大小。当然,编译器选项取决于您使用的编译器。您可能需要使用Fortran 2003语义或lhs变量的自动分配或类似功能


这是一个您应该注意的问题,因为如果您使用自动分配(或者如果您的编译器默认实现了它),将调用的结果分配给
function1
a
将重新分配
a

我不理解您的最后一句话,似乎建议将
function1
中分配的数组复制到
a
。我的理解是,在调用
function1
之后,函数分配的数组可以作为变量
a
访问,
function1
不会占用额外的内存。我认为,因为他在那里分配数组,所以需要内存来完成。那么,我假设情况并非如此?正如我(和其他人到目前为止!)理解的那样,函数将内存分配返回给调用已分配内存
a
的调用例程。只有一个内存分配。我现在明白了。很高兴了解未来。谢谢对于发布的代码(忽略错误的解除分配),有两个分配-每个分配语句一个。当包含函数引用的赋值语句完成时(即“在执行包含引用的最内部可执行构造之后”),函数结果的分配将自动取消分配。赋值“正确”只是将函数结果中的值复制到a。编译器在幕后可能很聪明,可以避免无意义的内存操作,但标准一致性程序的可观察结果必须是“似乎”这种行为。您完全正确,因为allocate语句是多余的,但只有在lhs的大小(或延迟长度参数或动态类型,如果合适)不匹配。否则,您可以中断F95代码。