Segmentation fault with array indexing in Fortran

Let A

and I

be arrays of integer type with dimension N. In general, it I

is a permutation of integers 1:N

. I want to do A(1:N) = A(I(1:N))

. For small, N

this works great, but I got Segmentation fault

when N

large. Here's an example of what I actually did:

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))

      

Is there a better way to do this?

+3


source to share


1 answer


It seems that A(I(1:N))

a valid syntax, at least in my testing ( gfortran 4.8

, ifort 16.0

, pgfortran 15.10

). One problem is that i

and i

are the same thing, and an array i

cannot be used in the intended do as you do. Replacing it with j

gives a program that works for me:

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

      

As for why you are seeing a segmentation fault, my guess is that you are running out of memory when the array sizes get huge. If you still have problems, I suggest the following.



Instead of using, A(1:N) = A(I(1:N))

you really need to use a loop like

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

      

It's more readable and easier to debug going forward.

0


source







All Articles