How to use strtok in C properly so there is no memory leak?

It's worth explaining that strtok does its job by:

  1. returning pointers that point INTO the original string; and

  2. replacing each separator character that it finds with NULL.

Thus, everything is in-place, and it does not need to allocate any memory.


In the comment in your question, you say that you "Call strtok on 'line' multiple times until it returns NULL". This sounds as if you may be using strtok incorrectly. The first time you call it, you should call it with 'line' as an argument; on subsequent calls, you should pass it NULL. Take the following as an example:

void function myFunc(char* line) {
  char *segment; // This will point at each delimited substring in turn.

  segment = strtok(line, " ");

  // Do something with segment.

  segment = strtok(NULL, " ");

  // Do something with the new segment.

  free(line);
}

As DrTwox said, though, your second example is better - 'line' should be freed by the same context that malloced it (or not), so the call to free() doesn't belong in this function. And you're better off looping it - something like:

void function myFunc(char* line) {
  char *segment;

  segment = strtok(line, " ");

  while (segment != NULL) {
    // Do something with segment.

    segment = strtok(NULL, " ");
  }
}

Invocation is like this:

char *line = malloc(20*sizeof(char));

// Check that malloc succeeded here.
// Put some data into 'line'.

myFunc(line);

free(line);

// No 'garbageLine' required.

The way that strtok works is a little complex to explain, but you've got the important parts - it doesn't allocate or free any memory. Instead, it works by modifying the string you passed to it.


strtok() will not free anything, as it has no knowledge of where the string is stored. It could be on the stack or the heap, it doesn't know or care! :)

Is it safer to do the following instead?

Your second example is much better, as it simplifies myFunc(), and makes it useful in more situations as the function does not need to know where the string is allocated. By removing the call to free() from myFunc() you are able to use the function to parse strings from the stack or the heap. The caller allocates the memory, the caller frees the memory!

Further reading: strtok()