在这里,我知道a只是长度为170的一维数组。
subroutine gonewrong(q,e,A)
implicit none
integer, dimension(:) :: q
integer, dimension(:,:), intent(in) :: e
integer, dimension(size(e,1)*2), intent(out) :: A
print *, A(2)
end subroutine gonewrong
例如,当我尝试找到(2)时,它会给我一个细分故障!E具有尺寸(85,2)。
是因为我在程序中用来编译它的程序中将A声明为可分配的数组?
我使用的程序:
program prog_1
use module_1
implicit none
integer::qm,a,b,c
integer,allocatable,dimension(:)::q
integer,allocatable,dimension(:,:)::e
!integer, dimension(size(e,1)*2) :: A
a = 5
b = 3
c = 10
allocate(q(a+c))
allocate(e(a+b*c,2))
call subr1(a,b,c,qm,q,e) !Outputs are qm,q and e.
call gonewrong(q,e,A) !gonewrong takes q and e as arguments
end program prog_1
要考虑的另一个问题是在声明中:
integer,allocatable,dimension(:,:)::e
integer, dimension(size(e,1)*2) :: A
在声明A
时,e
的大小是未定义的(零?)。如果A
的大小取决于e
的大小,则需要在编译时间固定e
的大小,或者将A
设置为可分配,并在设置e
的大小后将其分别分配。要点是,随着e
的大小变化,A
不会动态调整其大小。在这种情况下,看来A
的长度为零,因为size(e)
返回零,因为仅定义了e
的形状,而不是其大小。引用A(2)
可能会违反细分违规(读取阵列的末尾),这与您观察到的内容是一致的。
旁边:许多人从动态语言来到Fortran并没有意识到Fortran例程至少分为三个"区域"。一节包含用于导入外部资源的use
语句,声明和本地变量的声明部分,以及放置可执行语句的例程的主体(鼓励pedants读取语言规格;我在此处概括了在此处概括为Pragmatism的概括清酒)。implicit
语句将导入与声明分开,并通过惯例将声明与可执行的语句与裸露的continue
语句分开。continue
被视为可执行文件,因此,如果声明在第一个continue
之后出现。
错误很明显:
integer::qm,a
使a
单个整数号(标量)。
子例程需要一个数组:
integer, dimension(size(e,1)*2), intent(out) :: A
所以您在那里传递错误的东西:
call gonewrong(q,e,A) !gonewrong takes q and e as arguments
因为fortran是案例不敏感!您正在将标量整数a/A
传递给期望数组的子例程。
最好在子例程内使用相同的(:)
用于A
,让编译器告诉您您正在犯错。
参数是一个数组,因此您必须通过那里的数组。
注意:在您的原始代码中,您有此行评论
! integer, dimension(size(e,1)*2) :: A
当您有两行
时integer::qm,a
integer, dimension(size(e,1)*2) :: A
该程序不会编译,因为a/A
被声明了两次。
对我来说,您的实际意图还不清楚。您的评论
!gonewrong takes q and e as arguments
确实令人困惑。这三件事都是gonewrong
的参数。q
,e
和A
。