PDA

View Full Version : SIGSEGV error with pointer usage


X=YZ
12-30-2003, 03:55 AM
The error is rather opaque as the write statment executescorrectly within the routine GetIt; however, the write statement produces a SIGSEGV error in the main routine. I've tried to distill this down to the bare essentials. I'm running on Linux 9 with lf9562. I compile with the line:

lf95 -g -o a.out temp.f90

and execute with:

./a.out

which produces:

Allocation of Ar( 3 , 2 ) status = 0
Ar = 1
Ar = 4
Ar = 2
Ar = 5
Ar = 3
Ar = 6
jwe0019i-u The program was terminated abnormally with signal number SIGSEGV.

Error occurs at or near line 14 of MAIN__
error summary (Fortran)
error number error level error count
jwe0019i u 1
total error count = 1

The code is:
PROGRAM MAIN

IMPLICIT NONE

INTEGER, DIMENSION(:,:), POINTER :: pAr

INTEGER :: i, j, ii, jj

i = 3
j = 2

call GetIt (i, j, pAr)

write (*,*) pAr(1,1)

END PROGRAM MAIN
SUBROUTINE GetIt (i, j, pAr)

IMPLICIT NONE


INTEGER, INTENT(IN) :: i, j
INTEGER, DIMENSION(:,:), POINTER :: pAr

INTEGER :: ierr
INTEGER :: ii, jj
INTEGER, DIMENSION(:,:), ALLOCATABLE, TARGET :: Ar

ALLOCATE (Ar(i,j), STAT=ierr)

write (*,*) 'Allocation of Ar(',i,',',j,') status = ',ierr

do ii = 1, i
do jj = 1, j
Ar(ii,jj) = (jj-1)*i + ii
enddo
enddo

pAr => Ar

do ii = 1, i
do jj = 1, j
write (*,*) 'Ar = ',pAr(ii,jj)
enddo
enddo

END SUBROUTINE GetIt



Any insight is appreciated!
X=YZ

tzeis
12-30-2003, 07:55 PM
The problem here is that you are not following one of the rules of Fortran 90 programming, which means that your code is not standard conforming. The rule is that if your subroutine's dummy arguments are using Fortran 90 features (like pointer) you have to provide an interface in the main program for the subroutine. There are two ways to do this. You can use an interface block in your main program, in which case your program would look like this:

PROGRAM MAIN

IMPLICIT NONE

INTEGER, DIMENSION(:,:), POINTER :: pAr

INTEGER :: i, j, ii, jj

INTERFACE
SUBROUTINE GetIt (i, j, pAr)
IMPLICIT NONE
INTEGER, INTENT(IN) :: i, j
INTEGER, DIMENSION(:,:), POINTER :: pAr
END SUBROUTINE
END INTERFACE

i = 3
j = 2

call GetIt (i, j, pAr)

write (*,*) pAr(1,1)

END PROGRAM MAIN
SUBROUTINE GetIt (i, j, pAr)

IMPLICIT NONE


INTEGER, INTENT(IN) :: i, j
INTEGER, DIMENSION(:,:), POINTER :: pAr

INTEGER :: ierr
INTEGER :: ii, jj
INTEGER, DIMENSION(:,:), ALLOCATABLE, TARGET :: Ar

ALLOCATE (Ar(i,j), STAT=ierr)

write (*,*) 'Allocation of Ar(',i,',',j,') status = ',ierr

do ii = 1, i
do jj = 1, j
Ar(ii,jj) = (jj-1)*i + ii
enddo
enddo

pAr => Ar

do ii = 1, i
do jj = 1, j
write (*,*) 'Ar = ',pAr(ii,jj)
enddo
enddo

END SUBROUTINE GetIt


Alternatively, you could put the subroutine into a module, which automatically provides an interface:

PROGRAM MAIN

use foo

IMPLICIT NONE

INTEGER, DIMENSION(:,:), POINTER :: pAr

INTEGER :: i, j, ii, jj

i = 3
j = 2

call GetIt (i, j, pAr)

write (*,*) pAr(1,1)

END PROGRAM MAIN

module foo
contains
SUBROUTINE GetIt (i, j, pAr)

IMPLICIT NONE


INTEGER, INTENT(IN) :: i, j
INTEGER, DIMENSION(:,:), POINTER :: pAr

INTEGER :: ierr
INTEGER :: ii, jj
INTEGER, DIMENSION(:,:), ALLOCATABLE, TARGET :: Ar

ALLOCATE (Ar(i,j), STAT=ierr)

write (*,*) 'Allocation of Ar(',i,',',j,') status = ',ierr

do ii = 1, i
do jj = 1, j
Ar(ii,jj) = (jj-1)*i + ii
enddo
enddo

pAr => Ar

do ii = 1, i
do jj = 1, j
write (*,*) 'Ar = ',pAr(ii,jj)
enddo
enddo

END SUBROUTINE GetIt
end module


both of these examples give the following output:

Allocation of Ar( 3 , 2 ) status = 0
Ar = 1
Ar = 4
Ar = 2
Ar = 5
Ar = 3
Ar = 6
1