首页 > 解决方案 > Fortran 90 自动(?)分配可分配对象

问题描述

program test

    implicit none
    real(dp),allocatable :: a(:), b(:)

    allocate (a(10))

    a = 1.d0
(*) b = a

end program

在上面的代码中,我设置了两个可分配对象 -ab- 并且只a在代码中分配。我预计代码无法编译,但它编译得很好,而且似乎运行良好,而下面的代码执行类似的工作,显示 SEGFAULT。

program test_fail

   implicit none
   real(dp),allocatable :: a(:), b(:)
   integer              :: i

   allocate ( a(10) )

   a = 1.d0

   do i = 1, 10
      b(i) = a(i)
   enddo

end program

可以理解以前的代码b自动分配吗?

subroutine test_sub(a)

   implicit none

   real(dp),intent(inout) :: a(:,:)

   ...

end program

并且在上面的带有 shape-array 输入的子程序中,是否可以理解代码自动检测输入数组的大小a,并在子程序中分配自己的数组并释放它返回到它的上帧?

最后,当我将一个数组复制到另一个数组时,哪个更快?

program speed1

  implicit none
  real(dp), allocatable :: a(:,:,:), b(:,:,:)

  allocate( a(10000,10000,10000) )

  a = 1.d0

  b = a

end program
program speed2

  implicit none
  real(dp), allocatable :: a(:,:,:), b(:,:,:)
  integer               :: i, j, k

  allocate( a(10000,10000,10000), b(10000,10000,10000) )

  a = 1.d0

  do i = 1,10000
    do j = 1,10000
      do k = 1,10000
        b(i,j,k) = a(i,j,k)
      enddo
    enddo
  enddo

end program

标签: fortranallocationfortran90

解决方案


我没有太多时间,所以这可能相当压缩。还要注意,正如上面的评论中所指出的(为了突出和后代而在此处复制)代码的有效性以及此答案的有效性取决于版本(有关更多详细信息,请参阅此问题)。

如您所见,声明

b = a

将自动将数组分配为与 的元素b相同的大小(和形状),a并为其元素赋予与a. 这一切都符合标准。然而,声明

b(i) = a(i)

array左边没有 ,它有,array element在这种情况下,Fortran 不会自动分配数组。很不幸,但这是(我相信)语言标准不需要编译器发现错误的情况之一——这就是您在运行时发现错误的原因。您的编译器似乎与我最近体验过的其他编译器一样 - 实际上,没有元素b(1)可以分配 to 的值a(1)等等

至于子程序中的'分配'用语句

real(dp),intent(inout) :: a(:,:) 

那不完全一样。这里a假设形状,只是假设传递给例程的相应参数的形状(和值)。该标准没有说明这是如何完成的。大多数编译器不会复制数组(出于对 Fortran 程序员通常很重要的性能原因),但有些可能会,并且很容易构建大多数编译器将复制作为参数传递的数据结构的示例。

至于你的最后两个小码中哪一个更快 - 你为什么不告诉我们?


推荐阅读