2014-04-17 13 views
5

Ich habe ein Fortran-90-Programm mit gfortran kompiliert, das ein skalierbares 3D-Array auf eine Art und Weise erstellt, wie ich es möchte. Beim Laufen, erhalte ich folgende Fehlermeldung:Fortran 90 - "Segmentierungsfehler - ungültige Speicherreferenz" mit skalierbarem 3D-Array

Program received signal SIGSEGV: Segmentation fault - invalid memory reference. 

Backtrace for this error: 
#0 0x10542ee42 
#1 0x10542f60e 
#2 0x7fff8d7895a9 
#3 0x10542575e 
#4 0x105425975 
#5 0x105425d0e 
Segmentation fault: 11 

Ich glaube, das ein Speicherproblem mit dem großen 3D-Array ist, wie es funktioniert, wenn ich die Abmessungen abnehmen, aber ist es trotzdem, dies zu umgehen? Hier ist mein Code:

PROGRAM phantomtest 
IMPLICIT NONE 
    INTEGER, PARAMETER:: columns=34, rows=34, diags=((4*columns)-6), m=(4*columns)-6+(2*columns) 
    REAL, ALLOCATABLE, DIMENSION(:,:,:)::phantom 
    INTEGER :: i, j, k 
    CHARACTER (LEN=3) :: nstring, nullstring='' 

ALLOCATE(phantom(columns,rows,m)) 
phantom=0 

CALL Phantom_Making(phantom,columns,rows,diags,m) 

WRITE(nstring,FMT="(I3)"), columns 
PRINT*, nullstring 
DO k=1,m 
    DO i=1,columns 
    WRITE(*,FMT="("//nstring//"I2)") phantom(i,:,k) 
    END DO 
    PRINT *, nullstring 
END DO 

END PROGRAM phantomtest 
!--------------------------- 
SUBROUTINE Phantom_Making(phantom,columns,rows,diags,m) 
IMPLICIT NONE 
    INTEGER, INTENT(IN):: columns, rows, diags, m 
    REAL, DIMENSION(columns,rows,m), INTENT(INOUT) :: phantom 
    INTEGER :: i, j, k, l 

!Vertical and horizontal rays 
DO i=1,rows 
    phantom(:,i,i) = 1 
    phantom(i,:,i+(columns)+(diags/2)) = 1 
END DO 

!Diagonal rays 
phantom(1,2,1+columns) = 1 
phantom(2,1,1+columns) = 1 
phantom(1,columns-1,1+columns+(diags/2)+rows) = 1 
phantom(2,columns,1+columns+(diags/2)+rows) = 1 
j = columns-1 

DO k=2+columns, (diags/2)+columns 
    phantom(2:columns,:,k) = phantom(1:(columns-1),:,k-1) 
    IF (((k+1)-columns).LE.columns) phantom(1,k+1-columns,k)=1 
END DO 

DO l=columns+(diags/2)+rows+2, columns+(diags/2)+rows+1+(diags/2) 
    j = j-1 
    phantom(2:columns,:,l) = phantom(1:(columns-1),:,l-1) 
    IF (j.GT.0) phantom(1,j,l) = 1 
END DO 

END SUBROUTINE 
+0

Wenn Sie die '-g' Compiler-Option verwenden, ist das Backtrace sinnvoller. –

Antwort

5

Die Prüfungen, die viele Compiler haben, können Ihnen beim Debuggen helfen. Zum Beispiel mit gfortran:

gfortran -g -fcheck=all -Wall segf.f90 
segf.f90:5.17: 

    INTEGER :: i, j, k 
       1 
Warning: Unused variable 'j' declared at (1) 
~/f/testy/stackoverflow> ./a.out 
At line 50 of file segf.f90 
Fortran runtime error: Index '199' of dimension 3 of array 'phantom' outside of expected range (1:198) 

Andere Compiler haben ähnliche Optionen.

Ihre Schleifen werden mit solchen Werten von l ausgeführt, dass Sie auf das Array phantom außerhalb der Grenzen zugreifen.

Stellen Sie sicher, dass l über die korrekten Werte 1:m verfügt, oder dass die Abmessungen des Array-Phantoms korrekt auf diesen Bereich festgelegt sind (1:m).