2016-04-22 8 views
6

Ich habe Probleme herauszufinden, wo und warum ich einen Segmentierungsfehler erhalte.Segmentierungsfehler bei Verwendung von regexec/strtok_r in C

Ich schreibe ein C-Code, der den Benutzer zur Eingabe eines regulären Ausdrucks aufgefordert und es kompilieren und dann einen String mit mehreren Sätze eingeben:

int main(void){ 

    char RegExp[50]; 
    regex_t CompiledRegExp; 
    char *para; 
    char delim[] = ".!?,"; 
    char *sentence; 
    char *ptr1; 

    printf("Enter regular expression: "); 
    fgets(RegExp, 50, stdin); 

if (regcomp(&CompiledRegExp,RegExp,REG_EXTENDED|REG_NOSUB) != 0) {       

    printf("ERROR: Something wrong in the regular expression\n");       

    exit(EXIT_FAILURE);                 

    } 

    printf("\nEnter string: "); 

strtok_r verwendet wird, um die Zeichenfolge mit einem der aufzuspalten folgende Begrenzer.,?! und dann wird die resultierende Token (Satz) als String-Parameter in der regexec Funktion verwendet wird, die er sucht, um zu sehen, ob der reguläre Ausdruck zuvor kompilierten innerhalb des Token enthalten ist:

if(fgets(para, 1000, stdin)){ 

    char *ptr = para; 
    sentence = strtok_r(ptr, delim, &ptr1); 

    while(sentence != NULL){ 

     printf("\n%s", sentence); 

     if (regexec(&CompiledRegExp,sentence,(size_t)0,NULL,0) == 0) { 
     printf("\nYes"); 
     } else { 
     printf("\nNo"); 
     } 
     ptr = ptr1; 
     sentence = strtok_r(ptr, delim, &ptr1); 

    } 
    } 
regfree(&CompiledRegExp); 
} 

Es ist wahrscheinlich ein dummer Fehler, den ich bin Es wäre aber sehr hilfreich, irgendeine Hilfe bei der Suche nach den Gründen des Segfauls zu geben!

EDIT:Bewegt regfree an einen geeigneteren Ort. Es tritt jedoch immer noch ein Segmentfehler auf. Ich bin mir ziemlich sicher, dass es etwas damit zu tun hat, wie der reguläre Ausdruck eingelesen wird oder wie er in regexec verglichen wird. Ahnungslos, obwohl.

+0

Was ist mit dem Debugger? –

+0

Kompilieren Sie das Programm für das Debuggen, und führen Sie das Programm unter einem Debugger aus. Der Debugger wird Ihnen genau sagen, was passiert ist. – wallyk

+0

Der gdb-Debugger gibt mir keine Details - behauptet nur, dass ein segfault gefunden wurde – higz555

Antwort

3

Statt dessen:

char *para; 
fgets(para, 1000, stdin); 

: Schreibe:

char para[1000]; 
fgets(para, 1000, stdin); 

In der ersten Variante para ist ein Zeiger, irgendwo in Speicher zeigt, und auf diese irgendwo der Benutzer -Zentrierung wird geschrieben. Am wahrscheinlichsten zeigt para auf eine Adresse, die ungültig ist, Ihr Programm sofort abstürzt.

+0

Fehler bei der Segmentierung behoben - danke! Jetzt werden meine regulären Ausdrücke nicht korrekt analysiert. Zurück zum Zeichenbrett. – higz555

2

Sie riefen regfree innerhalb der Schleife. Beim zweiten Aufruf der Schleife rufen Sie regexec auf freigegebenem Speicher mit undefiniertem Verhalten auf.

0

Sie verwenden strtok_r() falsch.

Um eine Zeichenfolge mit strtok_r() zu analysieren, ist das erste Argument im ersten Aufruf ein Zeiger auf die Zeichenfolge, die Sie analysieren möchten. Nachfolgende Aufrufe an strtok_r(), dieselbe Zeichenfolge zu analysieren, sollten als erstes Argument NULL übergeben haben. Was machst du:

ptr = ptr1; 
sentence = strtok_r(ptr, delim, &ptr1); 

macht keinen Sinn.

+0

Mein Verständnis war, dass der Zeiger innerhalb von strtok_r auf die aufgeteilte Zeichenfolge zeigte, nachdem das Trennzeichen gefunden wurde, und so die Zeichenfolge rekursiv durchschneiden konnte. Für mich geht das. – higz555

+1

Sinn für mich. Ich benutze strtok_r oft so. – Joshua

Verwandte Themen