2016-06-20 23 views
0

Ich habe eine einfache Rekursionsprozedur für DFS geschrieben.Segmentierungsfehler in DFS

#include <stdbool.h> 

void mydfs(int ROWS, int COLS,char **A,int row, int col, bool **visited){ 
    static int rowAdjacencyParams[4] = {-1,0,1,0}; 
    static int colAdjacencyParams[4] = {0,1,0,-1}; 

    *(*(visited+col)+row) = true; 
    //visited[row][col] = true; 
    int i,newR,newC; 
    for(i = 0;i<4;i++){ 
     newR = row + rowAdjacencyParams[i]; 
     newC = col + colAdjacencyParams[i]; 

     if(((newR >=0) && (newR < ROWS)) && ((newC>=0) && (newC < COLS))){ 
      /*if((A[newR][newC] == 'X') && !visited[newR][newC]){ 
       mydfs(ROWS,COLS,A,newR,newC,visited); 
      }*/ 
     } 
    } 
} 

int black(char** A, int n1) { 
    int i,j,count = 0; 
    int cols = strlen(A[0]); 
    bool visited[n1][cols]; 

    memset(visited,0,sizeof(visited)); 


    for(i = 0;i<n1;i++){ 
     for(j = 0;j<cols;j++){ 
      if((A[i][j] == 'X') && !visited[i][j]){ 
       count++; 
       mydfs(n1,cols,A,i,j,visited); 
      } 
     } 
    } 


    return count; 
} 
int main(){ 
    int ROWS = 3; 
    int COLS = 7; 

    char P[ROWS][COLS]= {"OOOXOOO","OOXXOXO","OXOOOXO"}; 

    printf("Number of islands = %d",black(P,COLS)); 
    return 0; 
} 

AKTUALISIERT Hauptfunktion

Allerdings, wenn ich dies ausführen es gibt mir eine segmentation fault für Linie visited[row][col] = true;. Dann habe ich versucht, es in *(*(visited+col)+row) = true; zu ändern, aber immer noch den gleichen Segmentierungsfehlerfehler. Bitte erläutern Sie, warum ich diesen Fehler erhalte.

+1

'bool besucht [n1] [cols];' Dies ist nicht legal C++. Wählen Sie auch eine Sprache - es ist entweder C++ oder C. Ich sehe das 'C++' in dem Code, den Sie gepostet haben, nicht. Wenn es C++ ist, könnte die Benutzung von 'std :: vector > anstelle von Doppelsternzeigern verwendet werden/sollte – PaulMcKenzie

+0

Auch eine a [mcve], also auch eine' main' Funktion, die das demonstriert Das Thema. – PaulMcKenzie

+0

Das übergebene Array ist 2-D, das Funktionsargument ist ein Doppelstern. '* (* (visited + col) + row) = true;' hat keine Ahnung was die Zeilenlänge ist. Ich schlage vor, besucht + row * cols + col', oder vorzugsweise definieren Sie das Argument function, um mit dem Array übereinzustimmen, das Sie übergeben. –

Antwort

1

Zusätzlich zu den Zeichendaten von mehr als der Puffer des Arrays, wie durch die Kommentare darauf hingewiesen, darüber hinaus, dass ein anderer Fehler das ist:

int black(char** A, int n1) { 
//... 
for(i = 0;i<n1;i++){ 
    for(j = 0;j<cols;j++){ 
     if((A[i][j] == 'X') && !visited[i][j]){ /* A[i] is out of bounds */ 

Die n1 wird als die Anzahl der Spalten übergibt, das 7 ist. Allerdings, wenn Sie zurück zu main gehen, haben Sie dies:

int ROWS = 3; 
int COLS = 7; 

char P[ROWS][COLS]= {"OOOXOOO","OOXXOXO","OXOOOXO"}; 
printf("Number of islands = %d",black(P,COLS)); 

Die P Array nur drei Zeilen. Wenn also die Funktion black aufgerufen wird, wird davon ausgegangen, dass P 7 Zeilen hat, nicht 3 Zeilen. Dies führt dazu, A Array A[0], A[1], A[2], (gut), aber dann A[3], etc., was undefiniert Verhalten ist (und in Ihrem Fall, ein Absturz).

Sie müssen also Ihre Spalten-/Zeilenlogik korrigieren lassen.


Ich lasse Sie auf ein Geheimnis. Da Sie Ihre Frage ursprünglich als C++ markiert haben, habe ich mir die Zeit genommen, diese Doppelsterne in std::vector zu ändern und die at()-Funktion zu verwenden, um das Problem zu lokalisieren. Ich weiß, dass Sie Ihre Frage jetzt als C99 markiert haben, aber ich möchte nur wissen, warum Tags wichtig sind. Ich weiß nicht, ob C99 diese Eigenschaft hat, Randbedingungen wie diese automatisch zu erkennen.

+0

Vielen Dank, dass Sie diese Antwort gepostet und die 'n1' Sache geklärt haben. Ich habe die Korrekturen vorgenommen. Außerdem habe ich 'char ** A' in' charA [] [COLS] 'und' bool besucht [] [COLS] 'geändert. Jetzt läuft es erfolgreich. Aber die Ergebnisse, die es zurückgibt, sind 6. Das ist nicht erwünscht, da die Anzahl der '4-verbundenen' Komponenten eindeutig 3 ist. Auch habe ich das 'if ((A [newR] [newC] ==' X ') && (besucht [newR] [newC] == 0)) 'line ist immer' false'. Es sieht so aus, als würde das Array 'visited' nicht aktualisiert oder einfach nur eine neue Version davon kopiert, wenn ich es in einem rekursiven Aufruf übergebe. – user3243499

+0

Der neue Funktionsaufruf lautet 'void mydfs (int ROWS, int COLS, Zeichen A [] [COLS], int Zeile, int Spalte, int besucht [] [COLS])' – user3243499

+0

Und ich habe es rekursiv mit dieser Anweisung aufgerufen 'mydfs (ROWS, COLS, A, newR, newC, besucht);' – user3243499