2016-12-02 4 views
-1

Lassen Sie mich zunächst für die Formatierung und den schwierigen Code entschuldigen. Ich bin neu in C und Stack. Der Großteil des unordentlichen Codes hier ist wahrscheinlich irrelevant für das Problem, aber notwendig für den Kontext.Segmentierung Fehler während Realloc

Der folgende Code führt nach dem ersten Aufruf von realloc zu einem Segmentierungsfehler (in den Kommentaren notiert). return_file->target_line ist einfach ein 3D-Array, i ist eine Elementzahl der ersten Dimension des 3D-Arrays. Also rufe ich dazu auf, weitere 2D-Arrays (vom Typ char **) zu speichern.

NULL Rückgaben von Speicherzuweisungen wurden absichtlich weggelassen b/c das Entwicklungsprotokoll speziell angegeben alle Speicherzuweisungen werden erfolgreich sein (woran ich zweifle).

Ich verwende mein eigenes Speicherprüfprogramm. Der Fehlercode ich erhalte, ist:

Program received signal SIGSEGV, Segmentation fault. 
0x00007ffff7ac63fb in reallochook() from /lib64/libc.so.6 

Ich habe für eine sehr lange Zeit sah es aber nicht zu finden scheinen, was das Problem ist.

Mockfile *read_mockfile(const char filename[]) { 
    Mockfile *return_file = NULL; 
    FILE *input; 

    if(filename != NULL && (input = fopen(filename, "r")) != NULL) { 
    char **split_tmp, line[MAX] = {0}; 

    return_file = malloc(sizeof(Mockfile)); 
    return_file->rule_count = 0; 

    /*read lines*/ 
    while(fgets(line, MAX, input) != NULL){ 
     if(line[0] != '#' && line[0] != '\n'){ 
     int j, i = return_file->rule_count; 
     split_tmp = split(line); 

     if(line[0] != '\t'){ 
      j = 0; 


      /*target line. Realloc every string in three steps. Segementation fault occurs after this line below.*/ 
      return_file->target_line = realloc(return_file->target_line, (i + 1) * sizeof(char **)); 

      while(split_tmp[j] != NULL){ 
      return_file->target_line[i] = realloc(return_file->target_line[i], (j + 1) * sizeof(char *)); 
      return_file->target_line[i][j] = malloc(strlen(split_tmp[j]) + 1); 
      strcpy(return_file->target_line[i][j], split_tmp[j]); 
      j++; 
      } 
      return_file->target_line[i] = realloc(return_file->target_line[i], (j + 1) * sizeof(char *)); 
      return_file->target_line[i][j] = NULL; 
     } else { 
      j = 0; 

      /*action line. Allocate every string in three steps*/ 
      return_file->action_line = realloc(return_file->action_line, (i + 1) * sizeof(char **)); 

      while(split_tmp[j] != NULL){ 
      return_file->action_line[i] = realloc(return_file->action_line[i], (j + 1) * sizeof(char *)); 
      return_file->action_line[i][j] = malloc(strlen(split_tmp[j]) + 1); 
      strcpy(return_file->action_line[i][j], split_tmp[j]); 
      j++; 
      } 
      return_file->action_line[i] = realloc(return_file->action_line[i], (j + 1) * sizeof(char *)); 
      return_file->action_line[i][j] = NULL; 

      return_file->rule_count++; 
     } 
     } 
    } 
    fclose(input); 
    } 
    return return_file; 
} 
+0

@MD XF, sprechen Sie gerade über die geschweiften Klammern, die nicht auf einer neuen Linie sind? b/c das ist eine persönliche Vorliebe, die ich absichtlich behalte. –

+0

Was für Sie funktioniert ... arbeitet für Sie. Aber es gibt ein paar wichtige Verbesserungen zu machen, einige kleine Details, die große Unterschiede machen –

Antwort

5

realloc() erwartet ihr erstes Argument auf einen gültigen Speicherblock-zu-Punkt oder NULL, so dass nach malloc() sollten Sie initialisieren:

return_file = malloc(sizeof(Mockfile)); 
return_file->rule_count = 0; 
return_file->target_line = NULL; /* Add this */ 

Dies sollte diesen Absturz beheben.

Beachten Sie auch, dass foo = realloc(foo, N); ein Fehler ist, da realloc()NULL zurückgeben kann, so dass Sie das für die Vollständigkeit behandeln müssen.

+0

Was ist der Grund dafür? Ist es für andere Zuweisungsfunktionen notwendig? d.h. 'malloc()' und 'calloc()'? –

+1

Auf welches "dieses" beziehen Sie sich? Der C-Standard definiert das Verhalten [wie auf dieser Seite angegeben] (http://en.cppreference.com/w/c/memory/realloc); Die 'NULL' Rückgabewertprüfung ist natürlich auch für' malloc() 'notwendig, aber aus verschiedenen Gründen. –