2016-04-11 18 views
0

Das Programm zielt darauf ab, das erste Wort und eine Reihe von verbleibenden Wörtern zu erhalten. Wenn beispielsweise line = "a bb cc dd ee", dann keya sein sollte, sollte keySet ein Zeiger auf ein Array von {bb,cc,dd,ee} sein.Zuweisungsspeicher zu Char **

Ich versuche, Speicher dynamisch char** keySet zuzuweisen, aber KeySet-Ausgabe immer ee ee ee ee. Es scheint, dass keySet nicht der Zeiger auf das erste Element des Arrays ist, sondern auf das letzte Element zeigt. Was ist das Problem in meiner Funktion?

void allocateKeySet(char* line){ 
    int count = 0; 
    char* token = strtok(line, " "); 
    char key[17]; 
    char tempKey[17]; 
    char** keySet; 

    sscanf(strtok(NULL, " "), " %s", key); 
    keySet = calloc(1, sizeof(char*)); 
    while((token = strtok(NULL, " ")) != NULL){ 
     sscanf(token, " %s", tempKey); 
     keySet[count++] = tempKey; 
     keySet = realloc(keySet, (count+2) * sizeof(char*)); 
    } 

    printf("key: %s\n", key); 
    printf("keySet: "); 
    for(int i = 0; i < count - 1; i++){ 
     printf("%s ", keySet[i]); 
    } 
} 

z.B. Linie:

"a bb cc dd ee" 

erwartete Ausgabe:

key: a 
keySet: bb cc dd ee 

Meine Ausgabe:

key: a 
keySet: ee ee ee ee 
+1

'keySet [count ++] = tempKey;': Wahrscheinlich möchten Sie 'str (n) cpy' oder' strdup'. Momentan wird 'tempKey' immer neu zugewiesen und alle' keySet' Elemente zeigen auf * den gleichen * 'tempKey'. Nach der letzten 'tempKey'-Zuweisung zeigen sie alle auf' 'ee''. (Beachten Sie, dass Sie, wenn Sie 'strcpy' verwenden, zuerst Speicher für' keySet [count ++] 'zuweisen müssen;' strdup' übernimmt die Zuweisung und Zuweisung auf einmal, aber Sie müssen trotzdem auf 'NULL' testen danach.) – Evert

+0

meinst du: 'strdup (keySet [count ++], tempKey)'? –

+0

Fast: 'keySet [count ++] = strdup (tempKey)'. Teste nachher 'keySet [count-1]! = NULL' danach (unwahrscheinlich, aber die richtige Sache). – Evert

Antwort

1

keySet[count++] = tempKey;: Sie wollen wahrscheinlich str(n)cpy oder strdup. Derzeit wird tempKey jedes Mal neu zugewiesen und alle keySet Elemente zeigen auf dasselbetempKey. Nach der letzten tempKey Zuweisung zeigen sie alle auf "ee". (Beachten Sie, dass, wenn Sie strcpy verwenden, werden Sie Speicher zuweisen müssen für keySet[count++] zuerst; strdup funktioniert die Zuweisung und Zuteilung in einem Rutsch, aber Sie werden für NULL sowieso danach testen.)

So:

while((token = strtok(NULL, " ")) != NULL){ 
     sscanf(token, " %s", tempKey); 
     keySet[count] = strdup(tempKey); 
     if (keySet[count] == NULL) { 
      perror("memory allocation failure"); 
     } 
     count++; 
     keySet = realloc(keySet, (count+2) * sizeof(char*)); 
    } 

Wenn Sie nicht strdup verwenden können, können Sie die folgenden Zeilen anstelle der strdup Zeile verwenden:

keySet[count] = malloc(strlen(tempKey)+1); 
// test for keySet[count] 1= NULL 
strcpy(keySet[count], tempKey) 
count++; 

gemäß this answer.

Vergessen Sie nicht, die einzelnen keySet Elemente danach zu befreien.

+0

Wenn ich 'strcpy' verwenden möchte, wie kann ich Speicher für' keySet [count ++] 'zuweisen? Etwas wie 'keySet [count ++] = char [strlen (tempKey)]'? Cuz 'strdup' scheint nicht in der Standard-C-Bibliothek zu sein und ich kann es nicht in meinen Hausaufgaben verwenden ... –

+0

Welches OS verwendest du? 'strdup 'ist ein POSIX.1-2001-Standard und ist in den meisten C-Bibliotheken enthalten. – Evert

+0

Auch: http://stackoverflow.com/questions/14020380/strcpy-vs-strdup – Evert