Fortran 90 自动(?)分配可分配对象

标签 fortran allocation fortran90

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

还有在上面的子程序中输入整形数组,可以理解代码自动检测输入数组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

最佳答案

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

如你所见,声明

b = a

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

b(i) = a(i)

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

至于子程序中的'allocation'语句

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

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

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

关于Fortran 90 自动(?)分配可分配对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62534248/

相关文章:

FORTRAN 77 除以零行为

macos - gfortran 是否可以使用 MOLD 进行分配?

python - 在不知道数据大小的情况下从文件中读取 float 作为 numpy 数组

fortran - MPI_SCATTER Fortran 矩阵(按行)

c++ - 释放动态分配的内存

c++ - 在 C/C++ 应用程序中使用 Fortran90 模块

matlab - Matlab vs.Julia vs.Fortran的速度

fortran - `MPI_ERR_TRUNCATE: message truncated` 错误

fortran - Fortran 2008 中的非多态过程重载延迟过程

c++ - C++库应如何允许自定义分配器?