Code:
/* count_tokens: Computes the number of tokens in 's'. */
size_t count_tokens(const char *s);
/* copy_tokens: Splits 's' into multiple strings and assigns a pointer to each one in '*a'. Terminates with a null pointer. */
char **copy_tokens(char **a, char *s);
/* tokenise: Makes a copy of s, allocates the necessary storage for the array, stores each token in the array, and returns it (using both of the functions listed above). */
char **tokenise(const char *s);
If you have a complicated tokenisation process, as you may if you were writing a complicated line-parser for a shell, you could write a finite state machine in a generic manner that would allow you to use it with both count_tokens and copy_tokens, leading to a simple implementation for both of those functions.
The tokenise function really only requires two calls to malloc. If whitespace may be present before the tokens, you can allocate an extra pointer, store it in the first element, then return a pointer to the second element of the array. That will allow you to free the copy of 's' later on.