标签: allocatable-array

Fortran 函数返回可分配数组

让我考虑一个返回一个的函数allocatable数组的函数。是否应该在赋值之前分配保存结果的数组变量(在函数外部)?

\n

例如,考虑以下程序

\n
program mem\n  implicit none\n\n  interface\n     function get_matrix() result(res)\n       real(kind=kind(0.d0)), allocatable :: res(:,:)\n     end function get_matrix\n  end interface\n  \n  real(kind=kind(0.d0)), allocatable :: w(:,:)\n\n  allocate(w(2,2)) ! Is this necessary?\n  w=get_matrix()\n  deallocate(w)\n\nend program mem\n\nfunction get_matrix() result(res)\n  real(kind=kind(0.d0)), allocatable :: res(:,:)\n\n  allocate(res(2,2))\n  res = 0.d0\n  res(1, 1) = 1.d0\n  res(2, 2) = 1.d0\nend function get_matrix\n
Run Code Online (Sandbox Code Playgroud)\n

根据thisthisres ,为 的 结果分配的数组get_matrix一旦超出范围就会被释放。

\n

w对主程序中未分配变量的赋值是否会延长结果的范围get_matrix?换句话说,如果我allocate(w(2,2))在主程序中省略,我会得到未定义的行为吗?

\n

省略allocate(w(2,2))并使用gfortran …

fortran function allocatable-array

7
推荐指数
2
解决办法
2725
查看次数

用户定义类型的Fortran可分配数组成员

在下面的简单程序中,我陷入了派生类型的可分配数组成员的分段错误。此分段错误仅在我尝试过的一台计算机(在openSUSE上使用Intel Fortran 14.0.3)上,而在另一台计算机(在Ubuntu上使用Intel Fortran 14.0.2)上则没有。另外,如果我更改程序中的整数参数之一,程序将正常结束。

有人能重现这个问题吗?有人可以告诉我代码有什么问题吗?

以下是三个源代码文件。

main_dbg.f90 ..是否发生分段错误取决于n1and n2在此文件中的值。

PROGRAM dbg
  USE tktype
  USE mymodule, ONLY : MyClass, MyClass_constructor
  IMPLICIT NONE

  INTEGER(I4B)                :: n1,n2,n3
  TYPE(MyClass)               :: o_MyClass

  n1=23
  n2=32
  ! .. this does not work.
  ! n2=31 
  ! .. this works.
  n3 = n1*n2
  write(*,'(1X,A,I10)') 'n1=', n1
  write(*,'(1X,A,I10)') 'n2=', n2
  write(*,'(1X,A,I10)') 'n3=', n3

  o_MyClass = MyClass_constructor(n1, n2, n3) 

  call o_MyClass%destructor()
  write(*,*) '***************************'
  write(*,*) '   Normal End :)           '
  write(*,*) '***************************'

END PROGRAM dbg
Run Code Online (Sandbox Code Playgroud)

strange.f90 ..分段错误发生forall …

fortran memory-management segmentation-fault allocatable-array

5
推荐指数
1
解决办法
582
查看次数

从名称列表中读取可分配数组

我正在使用GNU Fortran(GCC)4.8.2

我想从名称列表中读取可分配数组。但是我事先不知道必须向可分配数组中读取多少个元素,因此我无法在读取名称列表之前对其进行分配。

这是我的名单:namelist.nml:

&SECTION_1
    intList = 5,6,7
&END
Run Code Online (Sandbox Code Playgroud)

这是我的程序:namelist.f08:

program namelist
    implicit none

    integer, allocatable    :: intList(:)
    integer                 :: U    ! Unit to read the namelist file

    namelist /SECTION_1/ intList

    !allocate(intList(3)) ! <-- If I uncomment this, the program works.
    open(NEWUNIT=U, file="namelist.nml", status='OLD', recl=80, delim='APOSTROPHE')
    rewind(U)
    read(U, nml=SECTION_1)
    close(U)

    write (*,*) intList
end program namelist
Run Code Online (Sandbox Code Playgroud)

如果我取消标记行的注释,程序将运行,但是,正如我之前说的,我无法在分配之前读取名称列表。有人知道如何做到这一点吗?

fortran configuration-files allocatable-array

5
推荐指数
1
解决办法
687
查看次数

Fortran 可分配的内部存储器表示

我想知道 fortran 可分配数组的内部存储器表示是什么。

我理解这比原始指针更复杂一点,因为形状和等级也必须存储。

我还猜测它依赖于实现,因为我在Fortran 2003 标准中找不到信息

但是,我想知道使用哪种结构来表示可分配数组(即使只针对一个编译器)。

我知道这个问题有点宽泛,但我们将不胜感激。

fortran allocatable-array

5
推荐指数
1
解决办法
548
查看次数

Fortran 分配(重新)分配和 gfortran 警告

一个简单的代码:

\n\n
program main\ninteger, allocatable :: A(:,:)\ninteger              :: B(3,4)\nB=1\nA = B  !A will get allocated, with the same shape and bounds as B\nend program main\n
Run Code Online (Sandbox Code Playgroud)\n\n

编译上面的代码:gfortran-8 -std=f2008 -fcheck=all -Wall -Wextra -fbounds-check -fimplicit-none array.f90

\n\n

我收到以下警告:

\n\n

Warning: \xe2\x80\x98a.offset\xe2\x80\x99 may be used uninitialized in this function\nWarning: \xe2\x80\x98a.dim[0].lbound\xe2\x80\x99 may be used uninitialized in this function \nWarning: \xe2\x80\x98a.dim[0].ubound\xe2\x80\x99 may be used uninitialized in this function [-Wmaybe-uninitialized]

\n\n

有人知道我为什么收到这些警告吗?

\n

fortran gfortran compiler-warnings gcc-warning allocatable-array

5
推荐指数
1
解决办法
842
查看次数

Fortran:选择可分配数组的等级

我正在尝试编写一个程序,其中我希望可分配数组的A等级为 1、2 或 3,具体取决于我在运行时的输入。我想这样做,因为后续操作A是相似的,并且我在模块中定义了一个work带有模块过程的接口,当执行该模块过程时A,会给出所需的结果。

我目前正在做的是这样的:

program main
implicit none
integer :: rank,n=10
real*8, allocatable :: A1(:)
real*8, allocatable :: A2(:,:)
read (*,*) rank

if (rank.eq.1) then
    allocate (A1(n))
else if (rank.eq.2) then
    allocate (A2(n,n))
end if

! operate on the array
if (rank.eq.1) then
    call work(A1)
else if (rank.eq.2) then
    call work(A2)
end if

end program
Run Code Online (Sandbox Code Playgroud)

如果我可以选择 的等级A,事情会容易得多,因为这样就if不需要这些陈述了。也许这是不可能的,但感谢所有帮助。

arrays fortran rank allocatable-array

4
推荐指数
1
解决办法
2368
查看次数

指向包含可分配数组的派生类型的指针

一般来说,我想重命名派生类型中的可分配变量,这些变量通过子例程参数传递.使用'derived%type_xx'编写所有内容并不是那么令人愉快.此外,我不想花费额外的内存来将派生类型的值复制到一个新的变量,这需要新的分配内存.此外,我知道可分配数组比指针更受欢迎,原因有很多.我尝试定义指向可分配变量的指针,但失败了.我试过这个,因为我想简化我的代码,既可读也不太长.我想知道是否有办法实现目标?谢谢.

这是演示代码:

Module module_type
IMPLICIT NONE
    TYPE type_1
        REAL,ALLOCATABLE                  ::      longname_1(:), longname_2(:)
    END TYPE
END MODULE

!------------------------------------------------------------------------------------------
SUBROUTINE TEST(input)
    USE MODULE module_type
IMPLICIT NONE
    TYPE(type_1)                          ::      input
    input%longname_1 = input%longname_1 + input%longname_2   ! Use one line to show what I mean
END SUBROUTINE
Run Code Online (Sandbox Code Playgroud)

这是失败的:

Module module_type
IMPLICIT NONE
    TYPE type_1
        REAL,ALLOCATABLE                  ::      longname_1(:), longname_2(:)
    END TYPE
END MODULE

!------------------------------------------------------------------------------------------
SUBROUTINE TEST(input)
    USE MODULE module_type
IMPLICIT NONE
    TYPE(type_1),TARGET                    ::      input

    REAL,POINTER                           ::      a => input%longname_1 &
                                                 & b => input%longname_2

    a …
Run Code Online (Sandbox Code Playgroud)

fortran pointers derived-types allocatable-array

3
推荐指数
1
解决办法
1372
查看次数

在Fortran中读取带有名称列表的可分配字符串

由于Fortran 2003可以使用可变长度的字符串.我不想以古老的方式工作并声明一个恒定的字符串长度,而是想动态地读取我的名单中的字符串.

考虑一下该计划

program bug

  implicit none

  character(:), allocatable :: string
  integer :: file_unit

  namelist / list / string

  open(newunit=file_unit,file='namelist.txt')

  read(unit=file_unit,nml=list)
  write(*,*) string

  close(file_unit)

end program bug_namelist
Run Code Online (Sandbox Code Playgroud)

以及namelist.txt文件中包含的小名单:

&list
string = "abcdefghijkl"
/
Run Code Online (Sandbox Code Playgroud)

如果我用GCC 8.2.0编译带有激进的调试标志,我得到

Warning: ‘.string’ may be used uninitialized in this function [-Wmaybe-uninitialized]
Run Code Online (Sandbox Code Playgroud)

在runtine,什么都没有打印出来,这就出现了:

Fortran runtime warning: Namelist object 'string' truncated on read.
Run Code Online (Sandbox Code Playgroud)

使用具有类似调试标志的英特尔编译器17.0.6,没有编译时标志和以下运行时错误:

forrtl: severe (408): fort: (7): Attempt to use pointer STRING when it is not associated with a target
Run Code Online (Sandbox Code Playgroud)

这表明namelist功能无法"自行"分配可变长度字符串,因为如果我添加该行

allocate(character(len=15) :: string)
Run Code Online (Sandbox Code Playgroud)

错误消失了.这是预期的行为吗?或者它是编译器的缺陷?

string fortran character allocatable-array

3
推荐指数
1
解决办法
246
查看次数

如何跨子例程处理模块中的 Fortran 全局可分配变量

我有以下模块,其中包含一个可分配变量,该变量在模块中定义,在子例程中分配,然后也在第一个子例程调用的第二个子例程中使用。在这种情况下,我是否必须将变量传递给第二个子例程并声明INTENT(inout)?或者因为它是一个全局变量,所以不需要作为参数传递?

MODULE test

  IMPLICIT NONE
  SAVE

  REAL,ALLOCATABLE,DIMENSION(:,:,:) :: total

CONTAINS

  !--- 1st subroutine
  SUBROUTINE my_subr1(n,m,z)
    IMPLICIT NONE
    INTEGER,INTENT(in) :: n,m,z
    ALLOCATE(total (n,m,z))
    total=.9
    CALL my_subr2(n)

  END SUBROUTINE my_subr1

  !-- 2nd subroutine
  SUBROUTINE my_subr2(n)
    IMPLICIT NONE
    INTEGER,INTENT(in) :: n

    total(n,:,:)=total(n-1,:,:)
  END SUBROUTINE my_subr2
END MODULE test
Run Code Online (Sandbox Code Playgroud)

fortran module global-variables allocatable-array

3
推荐指数
1
解决办法
1055
查看次数

intent(out) and allocatable Fortran arrays: what is really done?

I read on many posts on Stack Overflow that an allocatable array is deallocated when it is passed in a subroutine where the dummy argument is intent(out).

If I consider the following code :

program main

 real, dimension(:), allocatable :: myArray
 integer :: L=8

 allocate(myArray(1:L))
 call initArray(myArray)
 print *, myArray
 
contains

 subroutine initArray(myArray)
 real, dimension(:), intent(out) :: myArray

 myArray(:) = 10.0
 
 end subroutine initArray
 
end program main
Run Code Online (Sandbox Code Playgroud)

输出是正确的。因此,当发生释放时,内存被释放,但数组形状保持不变。准确吗?任何详细的解释将不胜感激。

我阅读了有关该主题的不同帖子(我可以在 Fortran 中使用可分配数组作为意图(输出)矩阵吗?将可分配变量传递到具有不可分配参数的子例程的效果是什么?,...)。所以我知道数组已被释放,但我想了解这是什么意思,因为在我的代码中,大小被保留,而且我也对这段代码的工作原理感到惊讶。

fortran allocatable-array

3
推荐指数
1
解决办法
431
查看次数

当从g95移动到gfortran时,"可分配数组必须具有延迟形状"

当从使用g95编译器转换到gfortran时,当我尝试编译之前已经工作的代码时出现以下错误

Error: Allocatable array ' ' at (1) must have a deferred shape
Run Code Online (Sandbox Code Playgroud)

这发生在我所有可分配数组的所有子程序中.一个例子如下.

    SUBROUTINE TEST(name,ndimn,ntype,nelem,npoin,nface,inpoel,coord,face)

    IMPLICIT  NONE

    integer:: i, j,testing
    integer, INTENT(OUT)::ndimn,ntype,nelem,npoin,nface
    integer, allocatable, dimension(1:,1:), INTENT(OUT)::inpoel
    real::time, dummy
    real, allocatable, dimension(1:,1:), INTENT(OUT)::coord
    integer, allocatable, dimension(1:,1:), INTENT(OUT)::face

    character(len=13)::name
    character(len=11)::name3

    name='testgrid.dat'
    name3='testgeo.dat'

    open (unit=14, file='testgrid2.dat', status='old')

    read(14,*)
    read(14,*)
    read(14,*)
    read(14,*) ndimn, ntype
    read(14,*)
    read(14,*) nelem, npoin, nface
    read(14,*)

    allocate(inpoel(ntype,nelem+1),coord(ndimn,npoin+1),face(ntype,nface+1))
Run Code Online (Sandbox Code Playgroud)

如何使用gfortran编译此代码?

fortran gfortran allocatable-array g95

1
推荐指数
1
解决办法
3590
查看次数

可分配数组及其自身值的分配

我想知道在现代 Fortran 中是否可以使用其本身或其中的一部分来分配可分配数组来执行此操作。这是一个简单的例子:

module modu
implicit none

type :: t
  integer :: i
end type

contains

subroutine assign(a,b)
type(t), allocatable, intent(out) :: a(:) 
type(t),              intent(in)  :: b
allocate(a(1))
a(1) = b
end subroutine
end module

!----------------------

program test
use modu
implicit none
type(t), allocatable :: a(:)

allocate(a(1))
a(1)%i = 2
call assign(a, a(1))
print*, a(1)%i
end program
Run Code Online (Sandbox Code Playgroud)

此代码使用 ifort 18 给出正确的答案,并使用 gfortran 7.4 返回“分段错误”。

注意:原来的问题有点复杂,因为call assign(a, a(1))应该call assign(a, a(1)+b)用运算符 + 正确重载来替换,但结论(尊重 ifort 和 gfortran)是相同的。

注意:在fortran 重载赋值中检查自赋值的 …

fortran variable-assignment allocatable-array

1
推荐指数
1
解决办法
1080
查看次数