2017-08-24 2 views
0

tut habe ich den folgenden Code-Strings von Token aufgeteilt:Gabe eines char * als Programmargument Pausen während char [] nicht

char **strToWordArray(char *str, const char *delimiter) 
{ 
    char **words; 
    int nwords = 1; 
    words = malloc(sizeof(*words) * (nwords + 1)); 

    int w = 0; 
    int len = strlen(delimiter); 
    words[w++] = str; 
    while (*str) 
    { 
    if (strncmp(str, delimiter, len) == 0) 
    { 
     for (int i = 0; i < len; i++) 
     { 
     *(str++) = 0; 
     } 
     if (*str != 0) { 
     nwords++; 
     char **tmp = realloc(words, sizeof(*words) * (nwords + 1)); 
     words = tmp; 
     words[w++] = str; 
     } else { 
      str--; 
     } 
    } 
    str++; 
    } 
    words[w] = NULL; 
    return words; 
} 

Wenn ich dies tun:

char str[] = "abc/def/foo/bar"; 
char **words=strToWordArray(str,"/"); 

dann das Programm funktioniert gut, aber wenn ich das tue:

char *str = "abc/def/foo/bar"; 
char **words=strToWordArray(str,"/"); 

dann bekomme ich einen Segmentierungsfehler.

Warum ist das? Das Programm erwartet ein char* als Argument, warum ein char* Argument das Programm zum Absturz bringt?

+0

TL; DR: Ihre Modifizierung 'str', aber wenn man' char * str tun = "" 'Sie können nicht modifiziere diese Daten, weil du einen Zeiger auf den Speicher hast, den du nicht berühren darfst. 'char [] str =" "' ist eine Kopie, die du machen kannst, was immer du willst. – Chad

Antwort

1

Da die Funktion enthält:

*(str++) = 0; 

, die die Zeichenfolge modifiziert, die ihm übergeben wurde. Wenn Sie Folgendes tun:

char *str = "abc/def/foo/bar"; 

str verweist auf ein schreibgeschütztes Zeichenfolgenliteral. Siehe Abschnitt dem Titel Der Versuch, einen Stringliteral in dieser Frage zu ändern:

Definitive List of Common Reasons for Segmentation Faults

+0

Das macht jetzt Sinn. Ist es möglich, den Char-Zeiger beschreibbar zu machen? – buddy2891

+0

Lassen Sie es auf ein Array anstelle eines Literals zeigen. 'char str [] =" xxx "; char * str1 = str; ' – Barmar

+0

BTW, ist deine Funktion nicht die gleiche wie' strtok() '? – Barmar