Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays Fortran中数组索引的分段错误_Arrays_Indexing_Fortran - Fatal编程技术网

Arrays Fortran中数组索引的分段错误

Arrays Fortran中数组索引的分段错误,arrays,indexing,fortran,Arrays,Indexing,Fortran,设A和I为维数为N的整数类型数组。通常,I是整数1:N的排列。我想做A(1:N)=A(I(1:N))。对于较小的N这很好,但是当N较大时,我得到了分段错误。 下面是我实际做过的一个例子: integer N integer,dimension(:),allocatable::A,I N = 10000000 allocate(A(N)) allocate(I(N)) A = (/ (i,i=1,N) /) I = (/ (N-i+1,i=1,N) /) A(1:N) = A(I(1:N)) 有

A
I
为维数为N的整数类型数组。通常,
I
是整数
1:N
的排列。我想做
A(1:N)=A(I(1:N))
。对于较小的
N
这很好,但是当
N
较大时,我得到了
分段错误。
下面是我实际做过的一个例子:

integer N
integer,dimension(:),allocatable::A,I
N = 10000000
allocate(A(N))
allocate(I(N))
A = (/ (i,i=1,N) /)
I = (/ (N-i+1,i=1,N) /)
A(1:N) = A(I(1:N))
有更好的方法吗?

似乎
a(I(1:N))
是有效的语法,至少在我的测试中(
gfortran 4.8
ifort 16.0
pgfortran 15.10
)。一个问题是
i
i
是同一件事,数组
i
不能像您所做的那样用于隐含do。将其替换为
j
将生成一个为我运行的程序:

program main
   implicit none

   integer :: N, j
   integer, allocatable, dimension(:) :: A, I

   ! -- Setup
   N = 10000000
   allocate(A(N),I(N))
   A = (/ (j,j=1,N) /)
   I = (/ (N-j+1,j=1,N) /)

   ! -- Main operation
   A(1:N) = A(I(1:N))

   write(*,*) 'A(1): ', A(1)
   write(*,*) 'A(N): ', A(N)

end program main
至于为什么会出现分段错误,我想当数组大小变大时,内存就会耗尽。但是,如果你仍然有问题,我建议如下

不要使用
A(1:N)=A(I(1:N))
,而应该使用循环,例如

! -- Main operation
do j=1,N
   Anew(j) = A(I(j))
enddo
A = Anew

这更具可读性,更易于调试。在您的示例中,i是一个数组,您是否将其用作循环变量?这可能吗?值得一提的是,在隐含do循环中使用专用的
ii
变量,即使
N
=100M(gfortran v.5.4),代码也能正常执行。为了明确这一点,Fortran不区分大小写,因此
I
I
引用相同的变量。My gfortran在(1)处给出
错误:循环变量不能是子组件
且无法编译。您的上一个循环不正确,因为您将在r.h.s上访问
a
的更改值。我认为您需要先制作一个副本以使用这样的循环。这样更好。我猜
A(1:N)=A(I(1:N))
无论如何都会导致编译器在幕后进行复制..在我使用ifort-16的linux设备上,上面的程序会以N>~4*10^6进行分段,因为它的堆栈大小约为10 MB。我猜ifort正在为整个数组分配生成一个临时数组,这可能会导致segfault。gfortran不会出现这种情况,但对于
-fstack阵列
,它再次给出segfault(使用堆栈大小为8.5 MB的mac mini)。(因为OP说“代码适用于小N”,可能
i
i
只是打字错误…?)对吧。特别地分配一个副本(这将为新的
重新进行
)将使过程更加透明,并在默认情况下将其放在堆上。对不起,
I
I
是打字错误。。。复制一份解决问题的方法。这可能是内存问题。我没有尝试使用gfortran,但我在不同的计算机上使用了ifort,更大的内存允许更大的N。谢谢大家。