Search code examples
cinstance-variablesstrtok

Keeping strok tokens after the initialization function ends in C


I have a function foo() that uses strtok() to tokenize a string and sends the tokens to fee(char *new_word) where I need to assign it to a new node. Now that's all well and good, but when foo() and fee() end I need to run bar() that prints the linked list, and from what I can tell the data in the node pointers gets corrupted and I can't use it. How can I hold onto the tokens?

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;
}

Solution

  • Tokens point to memory locations inside the memory block of your original string. When the original string is freed, the tokens will point to garbage. If you want to hold onto the tokens, you must either not free the original string or create a copy of each token (i.e. use strcpy or strdup - see comment below).

    The line that is causing you issues is new_node->word = new_word; in fee(). Instead assigning the token pointer, you need to allocate memory for new_node->word and copy new_word into it. When foo is done executing, the string memory block is released. By the time bar executes, your tokens are pointing to unallocated memory.

    Alternatively, if you initialize char *str = "Some words go here"; in the main above foo(), and then pass str (i.e. foo(str)), that will also work since str will remain in scope. Just don't try to free new_node->word if you go this route, your program will crash.