Frage

Ich habe eine durch Tabulatoren getrennte Textdatei, die ich Parsen bin. Seine erste Spalte enthält Saiten des Formats chrX, wo X eine Menge von Zeichenketten bezeichnet, beispielsweise „1“, „2“, ..., „X“, „Y“.

Diese sind jeweils in einem char* gespeichert genannt chromosome, da die Datei analysiert wird.

Die Textdatei auf der ersten Spalte sortiert ist lexikographisch, das heißt, muß ich eine Anzahl von Zeilen mit „chr1“ ab, und dann „ChR2“, etc.

Bei jedem „CHRX“ -Eintrag, ich brauche eine andere Datei zu öffnen, die mit diesem Eintrag verknüpft ist:

FILE *merbaseIn;

// loop through rows...

if (chromosome == NULL)                                                                                                                                                   
    openSourceFile(&chromosome, fieldArray[i], &merbaseIn, GENPATHIN);                                                                                                      
else {                                                                                                                                                                    
    if (strcmp(chromosome, fieldArray[i]) != 0) { // new chromosome                                                                                                   
        fclose(merbaseIn); // close old chromosome FILE ptr                                                                                                                                                                                                                                    
        free(chromosome); // free old chromosome ptr                                                                                                                          
        openSourceFile(&chromosome, fieldArray[i], &merbaseIn, GENPATHIN); // set up new chromosome FILE ptr                                                                  
    }                                                                                                                                                                       
}  
// parse row

Ich habe die Funktion openSourceFile, die wie folgt definiert ist:

void openSourceFile (char** chrome, const char* field, FILE** filePtr, const char *path) {
    char filename[100];                                                                                                                                                           
    *chrome = (char *) malloc ((size_t) strlen(field));
    if (*chrome == NULL) {                                                                                                                                                        
        fprintf(stderr, "ERROR: Cannot allocate memory for chromosome name!");                                                                                                      
        exit(EXIT_FAILURE);                                                                                                                                                         
    }                                                                                                                                                                             

    strcpy(*chrome, field);                                                                                                                                                       
    sprintf(filename,"%s%s.fa", path, field);                                                                                                                                     

    *filePtr = fopen(filename, "r");                                                                                                                                              
    if (*filePtr == NULL) {                                                                                                                                                       
        fprintf(stderr, "ERROR: Could not open fasta source file %s\n", filename);                                                                                                  
        exit(EXIT_FAILURE);                                                                                                                                                         
    }                                                                                                                                                                             
}      

Das Problem ist, dass meine Anwendung beendet mit einem Segmentierungsfehler aus dem ersten Chromosom in dem zweiten geht (von chr1 zu chr2) auf der folgende Zeile, wo ich die erste Chromosom Datei zu schließen, die ich geöffnet:

fclose(merbaseIn);

Ich weiß, ich bin fclose einen NULL-Zeiger nicht vorbei, weil bis zur Segmentation Fault, ich Daten aus dieser Datei lese. Ich kann dies sogar wickeln in einem bedingten und ich bekomme immer noch den Fehler:

if (merbaseIn != NULL) {
    fclose(merbaseIn);
}

Außerdem weiß ich openSourceFile Werke (zumindest für chr1, wenn die erste Datei-Handle von FILE* Einrichtung), weil meine Anwendung chr1 Reihen analysiert und liest Daten aus der FILE* Quelldatei korrekt.

Was es über diesen fclose Aufruf ist, dass ein Segmentierungsfehler verursacht auftreten?

War es hilfreich?

Lösung

valgrind --db-attach=yes --leak-check=yes --tool=memcheck --num-callers=16 --leak-resolution=high ./yourprogram args

Es ist sehr wahrscheinlich, dass die segfault durch Speicherbeschädigung auf dem Heap verursacht, nicht alles, was die Einheimischen ist zu beeinflussen. Valgrind zeigt Ihnen sofort die ersten falschen Zugriff Sie machen.

Edit: Die --db-attach Option valgrind seit Release 3.10.0 im Jahr 2014 weiterentwickelt wurde in der Release Notes Zustand:

The built-in GDB server capabilities are superior and should be used
instead. Learn more here:

http://valgrind.org /docs/manual/manual-core-adv.html#manual-core-adv.gdbserver

Andere Tipps

ein Fehler, den ich feststellen, ist diese Zeile:

 *chrome = (char *) malloc ((size_t) strlen(field));

was sein soll:

 *chrome = (char *) malloc ((size_t) strlen(field)+1);

Das ist, weil eine Zeichenfolge, die eine Schließung 0 am Ende hat, die Sie auch für Platz zu machen haben

beste Vermutung ist, dass ein anderer Teil des Codes ist verderblicher Speicher durch einen Pufferüberlauf oder Ähnliche Fehler.

Obwohl es unwahrscheinlich ist, die Ursache zu sein, haben Sie eine mögliche Überlaufbedingung in Ihrem Dateinamen Array, wenn der vollständige Dateiname 100 Zeichen überschreitet.

Ich würde vorschlagen, einen Debugger für Änderungen in der Speicherstelle durch die merbaseIn Variable zu beobachten.

Allg Pointer Problem

C ist eine großartige Sprache, aber es erfordert, dass Sie Ihre eigenen Speicher verprügeln. Neben dem Problem zuvor erwähnt, wo der malloc 1 Byte kurz ist, können Sie andere Zeiger Probleme haben.

Ich würde vorschlagen, einen Speicher-Debugger verwenden. In der Vergangenheit Electric Fence war ziemlich beliebt, aber in diesen Tagen I mehr über valgrind hören. Es gibt viele andere Möglichkeiten.

Zusätzlich finden Fehler von reinier , ich vermute, dass:

free(chromosome);

sollte folgen:

chromosome = NULL;

, um eine mögliche Verwendung eines nicht mehr gültigen Wert zu verhindern.

, warum diese FILE ** filePtr wenn nur diese FILE * filePtr würde ausreichen? nur so ein Gedanke ...

valgrind mit memcheck ist auf jeden Fall das richtige Werkzeug, die Ursache des Segmentierungsfehler zu entdecken. Um einen Debugger mit valgrind zu verwenden, beachten Sie, dass die --db-attach Option valgrind veraltet ist seit Valgrind 3.10.0 im Jahr 2014 veröffentlicht wurde in der Release Notes Zustand:

The built-in GDB server capabilities are superior and should be used
instead. Learn more here:

http://valgrind.org /docs/manual/manual-core-adv.html#manual-core-adv.gdbserver

Überprüfen Sie jeden Ort, den Sie verwendet "malloc" und sehen Sie, wenn Sie einen Fehler gemacht haben.

Zum Beispiel habe ich anzog aus einer Datei in eine char Leseleitungen **, aber ich falsch malloced es als:

my_list = malloc(sizeof(char) * num_lines_found_in_file);

Wenn es hätte sein sollen:

my_list = malloc(sizeof(char*)* num_lines_found_in_file);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top