在 Fortran 中多次循环后访问派生数据类型



我有以下一段代码:

program testdatatype
integer(8), parameter :: Stot= 2 
integer(8), dimension(Stot) :: Nf
integer(8) :: f, s, Qind
integer(8), dimension(:, :), allocatable :: NqG
real(16), dimension(:, :, :), allocatable :: d3xnormfac
type NqGtype
integer(8), dimension(:, :), allocatable :: NqGvalT
end type NqGtype
type(NqGtype), dimension(Stot) :: NqGT
type d3xnormfactype
real(16), dimension(:, :, :), allocatable :: d3xnormfacvalT
end type d3xnormfactype
type(d3xnormfactype), dimension(Stot) :: d3xnormfacT
! ----------------------------------------------------
! LOOP 1.1:
do s= 1, Stot, 1
Nf(s)= 2d0
write(*, *) 'NfLoop1.1= ', Nf(s)
end do
! LOOP 1.2:
do s= 1, Stot, 1
write(*, *) 'NfLoop1.2= ', Nf(s)
end do
! ----------------------------------------------------
! LOOP 2.1:
do s= 1, Stot, 1
allocate(NqG(Nf(s), Stot))
do f= 1, Nf(s), 1
NqG(f, s)= 5d0
NqGT(s)%NqGvalT= NqG
write(*, *) 'NqGLoop2.1= ', NqG(f, s)
write(*, *) 'NqGTLoop2.1= ', NqGT(s)%NqGvalT(f, s)
end do
deallocate(NqG)
end do
! LOOP 2.2:
do s= 1, Stot, 1    
do f= 1, Nf(s), 1
write(*, *) 'NqGTLoop2.2= ', NqGT(s)%NqGvalT(f, s)
end do
end do
! ----------------------------------------------------
! LOOP 3.1:
do s= 1, Stot, 1                    
do f= 1, Nf(s), 1   
allocate(d3xnormfac(Nf(s), Stot, NqGT(s)%NqGvalT(f, s)))
do Qind= 1, NqGT(s)%NqGvalT(f, s)
d3xnormfac(f, s, Qind)= 153d12
d3xnormfacT(s)%d3xnormfacvalT= d3xnormfac
write(*, *) 'd3xnormfacLoop3.1= ', d3xnormfac(f, s, Qind)
write(*, *) 'd3xnormfacTLoop3.1= ', d3xnormfacT(s)%d3xnormfacvalT(f, s, Qind)
end do  
deallocate(d3xnormfac)
end do
end do
! LOOP 3.2:
do s= 1, Stot, 1                    
do f= 1, Nf(s), 1                       
do Qind= 1, NqGT(s)%NqGvalT(f, s)
write(*, *) 'd3xnormfacTLoop3.2= ', d3xnormfacT(s)%d3xnormfacvalT(f, s, Qind)
end do
end do
end do
! ----------------------------------------------------
end program testdatatype

我正在 mpif90 编译器上编译这个 .f90 文件。正如您在运行此代码时所看到的,很明显循环 1.1 中的write语句给出的与循环 1.2 中的语句相同,也就是说,Nf(:)的值对于循环 1.1 之外的所有 s 值都是正确的。这与循环 2.1 和循环 2.2 相同(这次创建派生数据类型)。循环 1 的输出如下所示:

NfLoop1.1=                     2
NfLoop1.1=                     2
NfLoop1.2=                     2
NfLoop1.2=                     2

我能够在创建它的循环(循环 2.1)之外为任何 f 和 s 值(在循环 2.2 中)调用数据类型NqGT(s)%NqGT(f, s)的任何正确值。到目前为止没有问题。当我使用循环 2 运行循环 1 变量时,给出了以下输出:

NfLoop1.1=                     2
NfLoop1.1=                     2
NfLoop1.2=                     2
NfLoop1.2=                     2
NqGLoop2.1=                     5
NqGTLoop2.1=                     5
NqGLoop2.1=                     5
NqGTLoop2.1=                     5
NqGLoop2.1=                     5
NqGTLoop2.1=                     5
NqGLoop2.1=                     5
NqGTLoop2.1=                     5
NqGTLoop2.2=                     5
NqGTLoop2.2=                     5
NqGTLoop2.2=                     5
NqGTLoop2.2=                     5

此外,当将循环1 变量运行到循环 2 派生数据类型(这些数据类型又与循环 3 一起使用)时,将给出以下输出:

NfLoop1.1=                     2
NfLoop1.1=                     2
NfLoop1.2=                     2
NfLoop1.2=                     2
NqGLoop2.1=                     5
NqGTLoop2.1=                     5
NqGLoop2.1=                     5
NqGTLoop2.1=                     5
NqGLoop2.1=                     5
NqGTLoop2.1=                     5
NqGLoop2.1=                     5
NqGTLoop2.1=                     5
NqGTLoop2.2=                     5
NqGTLoop2.2=                     5
NqGTLoop2.2=                     5
NqGTLoop2.2=                     5
d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.1=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.2=   -1.83360386755485123703987599430319601E-2466
d3xnormfacTLoop3.2=    0.00000000000000000000000000000000000      
d3xnormfacTLoop3.2=    0.00000000000000000000000000000000000      
d3xnormfacTLoop3.2=    0.00000000000000000000000000000000000      
d3xnormfacTLoop3.2=    0.00000000000000000000000000000000000      
d3xnormfacTLoop3.2=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.2=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.2=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.2=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.2=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.2=    0.00000000000000000000000000000000000      
d3xnormfacTLoop3.2=    0.00000000000000000000000000000000000      
d3xnormfacTLoop3.2=    0.00000000000000000000000000000000000      
d3xnormfacTLoop3.2=    0.00000000000000000000000000000000000      
d3xnormfacTLoop3.2=    0.00000000000000000000000000000000000      
d3xnormfacTLoop3.2=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.2=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.2=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.2=    153000000000000.000000000000000000000      
d3xnormfacTLoop3.2=    153000000000000.000000000000000000000

但是,当我尝试对循环 3.1 执行相同的操作时,我无法再获取派生数据类型d3xnormfacT(s)%d3xnormfacvalT(f, s, Qind)的所有正确值,也就是说,循环 3.2 中打印的数据类型不等于循环 3.1 中打印的相同数据类型的值(有些值是正确的,但其他值不正确)。我该如何解决这个问题?我一定缺少一些东西(指针和/或派生数据类型的分配?

在循环 3.1 中,您只设置了一个特定的索引d3xnormfac但然后将整个d3xnormfac数组分配给d3xnormfacT(s)%d3xnormfacvalT。由于d3xnormfac是解除分配的,然后多次分配,因此不能保证仍会设置以前分配的值。

由于您的特定循环顺序,d3xnormfac(:,1,:)中的值未初始化。根据编译器是否将d3xnormfac重新分配到同一位置以及内存是否已清理,这些值最终可能是正确的。对于我的英特尔(-assume realloc-lhs允许自动分配),大多数值都是正确的。如您所见,对于我的 gfortran,大多数值都是不正确的。行为也可能取决于真实的类型,这解释了你的观察。

查看此情况的一个好方法是在分配后初始化每个值。修改代码以将其添加到循环 3.1 中:

allocate(d3xnormfac(Nf(s), Stot, NqGT(s)%NqGvalT(f, s)))
d3xnormfac = -1234     ! -- Added this line
do Qind= 1, NqGT(s)%NqGvalT(f, s)

产生以下结果:

mach5% ifort -assume realloc_lhs -check all -warn all -traceback -g main.f90 && ./a.out 
NfIN=                      2
NfIN=                      2
NfOUT=                      2
NfOUT=                      2
NqGIN=                     15
NqGTIN=                     15
NqGIN=                     15
NqGTIN=                     15
NqGIN=                     15
NqGTIN=                     15
NqGIN=                     15
NqGTIN=                     15
NqGTOUT=                     15
NqGTOUT=                     15
NqGTOUT=                     15
NqGTOUT=                     15
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacIN=    153000000000000.000000000000000000      
d3xnormfacTIN=    153000000000000.000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=   -1234.00000000000000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000      
d3xnormfacTOUT=    153000000000000.000000000000000000

您可以看到仍设置为 -1234 的部分。

澄清后

我现在看到这个问题来自对可分配数组如何属于派生类型的误解。d3xnormfacT(s)%d3xnormfacvalT是它自己的可分配数组。它是等级 3,并且(在分配之前)未分配。它(通常)使用常规分配语句进行分配,例如:

allocate(d3xnormfacT(s)%d3xnormfacvalT((Nf(s), Stot, NqGT(s)%NqGvalT(f, s)))

没有这样做。您正在(无意中)使用 fortran 的高级功能绕过传统分配:自动左侧 (lhs) 分配。当为数组分配与其形状匹配的值时,将分配或重新分配数组以匹配。更多信息在这里: 在 Fortran 中分配时自动分配阵列

您的陈述:

d3xnormfacT(s)%d3xnormfacvalT= d3xnormfac

实际上是一次做两件事。首先,d3xnormfacT(s)%d3xnormfacvalT分配以匹配d3xnormfac的大小,因为d3xnormfacT(s)%d3xnormfacvalT匹配d3xnormfac的形状(三维)。其次,为新分配的d3xnormfacT(s)%d3xnormfacvalT分配了与d3xnormfac相同的值。(没有人指向其他任何东西。

您应该将代码更改为不使用此自动 lhs 分配。2003 年标准允许这种自动 lhs 分配,但某些编译器(英特尔直到 2017 年)故意默认不支持它。我个人认为这是危险和不直观的,所以我通常会避免它。对于不了解它的开发人员来说,此功能可能是一个"陷阱"。gfortran(我猜你正在使用,你只指定mpif90只是一个包装器)标志以防止这种情况发生-fno-realloc-lhs.

一旦你改变了你的代码,你就会更好地理解我的其余答案,这就是你看到你所做的问题的真正原因。

编辑:正如@eriktous指出的那样,循环 2 中也存在同样的问题,但循环顺序意味着输出中没有未初始化的值。我真的不明白为什么s同时索引派生数据类型和数组的最外层维度。也许是因为这只是一个玩具箱。如果要纵向扩展此代码,请务必修复这两个问题。

如@Ross所述,在分配后添加行d3xnormfac= 1234似乎可以确保初始化。当循环 2 更改为以下内容时:

! LOOP 2.1:
do s= 1, Stot, 1
allocate(NqGT(1)%NqGvalT(Nf(s), Stot))
allocate(NqG(Nf(s), Stot))
do f= 1, Nf(s), 1
NqG(f, s)= 5d0
write(*, *) 'NqGLoop2.1= ', NqG(f, s)
NqGT(1)%NqGvalT= NqG(:, :)      
write(*, *) 'NqGTLoop2.1= ', NqGT(1)%NqGvalT(f, s)
end do
deallocate(NqG)
deallocate(NqGT(1)%NqGvalT)
end do
! LOOP 2.2:
write(*, *) 'NqGTLoop2.2= ', NqGT(1)%NqGvalT(:, :)

直接分配派生数据类型数组时,解除分配数组时会发生以下错误:

Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0  0x103880e46
#1  0x10388060c
#2  0x7fff59ff8f59
#3  0x1039095d5
#4  0x10390975e
#5  0x10390d0dd
#6  0x10367fbef
#7  0x10367fc9e
Segmentation fault: 11 

因此,lhs 自动分配派生数据类型是最初未给出此错误的原因。当只分配d3xnormfacd3xnormfacT(s)%d3xnormfacvalT自动分配时,可以在 3 个循环之后访问正确的数组值而不会出错,因为派生的数据类型数组不会在内部循环中释放。只要派生的数据类型数组具有恒定的维度,我怀疑以后应该不是问题。至于数组值的完整初始化,@Ross的解决方案似乎有效。如果谨慎使用,在这种情况下,lhs 自动分配可以工作。

最新更新