2017-10-26 18 views
-1

Ich habe eine Funktion foo(), die strtok() verwendet, um eine Zeichenfolge zu token und sendet die Token zu Gebühr (char * new_word), wo ich es einem neuen Knoten zuweisen müssen . Nun, das ist alles gut und gut, aber wenn foo() und fee() enden, muss ich bar() ausführen, das die verknüpfte Liste druckt, und von dem, was ich sagen kann, die Daten in den Knotenzeiger wird beschädigt und ich kann nicht verwenden es. Wie kann ich die Token festhalten?Strok-Token bleiben nach der Initialisierung in C

struct node{ 
char *word; 
struct node *next; 
}; 

struct node top = NULL; 

void foo(){ 
char *str = "Some words go here"; 
char *token = NULL; 
token = strtok(str, "\n"); 
while (token){ 
    fee(token); 
    token = strtok(NULL, "\n"); 
} 
} 

void fee(char * new_word){ 
struct node *new_node = malloc(sizeof(struct node)); 
new_node->word = new_word; 
new_node->next = head; 
head = new_node; 
} 

bar(){ 
    while (top){ 
    printf("%s\n", top->word); 
    top = top->next; 
    } 
} 
int main(int argc, char *argv[]){ 
foo(); 
bar(); 
return 0; 
} 
+3

Wahrscheinlich benötigen Sie eine Kopie des Tokens. Zeigen Sie uns Ihren tatsächlichen Code. Stellen Sie [mcve] bereit. – BLUEPIXY

+0

** Vollständig und überprüfbar ** beinhaltet auch, dass Ihr Beispiel ein gültiger Code sein muss, der tatsächlich kompiliert wird. Bitte kopieren Sie Ihren echten Code in die Frage und schreiben Sie nicht etwas, das Ihrem Gedächtnis ähnlich ist. 'struct node top = NULL;' sollte Ihnen einen Fehler geben. – Gerhardh

Antwort

0

Token zeigen auf Speicherorte innerhalb des Speicherblocks Ihrer ursprünglichen Zeichenfolge. Wenn die ursprüngliche Zeichenfolge freigegeben wird, zeigen die Token auf Müll. Wenn Sie die Token behalten möchten, müssen Sie entweder die ursprüngliche Zeichenfolge nicht freigeben oder eine Kopie jedes Tokens erstellen (z. B. strcpy oder strdup verwenden - siehe Kommentar unten).

Die Linie, die Sie Probleme verursacht, ist new_node->word = new_word; in fee(). Anstatt den Token-Pointer zuzuweisen, müssen Sie Speicher für new_node->word reservieren und new_word hineinkopieren. Wenn foo beendet ist, wird der String-Speicherblock freigegeben. Zu der Zeit, die bar ausgeführt wird, zeigen Ihre Token auf nicht zugeordneten Speicher.

Alternativ, wenn Sie char *str = "Some words go here"; im main oben foo() initialisieren, und dann passiert str (d foo(str)), die auch seit str funktionieren wird in Rahmen bleiben. Versuchen Sie nicht, new_node->word zu befreien, wenn Sie diese Route gehen, wird Ihr Programm abstürzen.

+1

Oder strdup. Anstatt zu sagen: token = strtok (...); Gebühr (Token); 'könnte geändert werden in' token = strtok (...); Gebühr (strdup (Token)); ' –