Tokenizing string using strtok
The key point in tokenizing strings is that


  The number of resulting token would not be known in prior


One good approach is the one you have followed,


Allocate some memory
Use it
Allocate more if needed


I want to answer some of the questions that you have asked.


  Is it feasible to split this into several functions? Where would you
  split it?


As you see, there is the repetition of error handling (freeing up the argv array). Well this can be separated into another function.


  Is this easily readable to a more experienced C programmer?


Not sure of the level of expertise you mean, but I can read it and understand without any problems. I am a 2 year experienced C Professional.


  Any corner cases where it might break? Does it leak memory?


There is no obvious memory leak I could see in the program. But you can use tools like valgrind to detect such leaks.

I am just posting few code, that I would use, if I am given the same program.

int free_argv_q(struct queue *q)
{
    int i;
    int q_len = q_length(q);

    for (i = 0; i &lt; q_len; i++) {
        char *arg = dequeue(q);
        free(arg);
    }

    return 0;
}

int parse_cmdline(char ***argv, char *input)
{
    int i;
    int argc = 0;

    char *arg = NULL;
    char *token = NULL;

    struct queue q;

    token = strtok(input, " ");

    do {
        /* strdup may fail due to low memory */
        arg = strdup(token);

        if (arg == NULL) {
            free_argv_q(&amp;q);
            return 0;
        }

        /* add to queue */
        enqueue(&amp;q, arg);
        token = strtok(NULL, " ");
    } while (token);

    /* length of the queue is the number of splits */
    argc = q_length(&amp;q);

    *argv = malloc(argc * sizeof(char *));

    if (*argv == NULL) {
        free_argv_q(&amp;q);
        return 0;
    }

    /* now we have all memory allocated */
    for (i = 0; i &lt; argc; i++)
        argv[i] = dequeue(&amp;q);

    return argc;
}


The explanation is as follows.


I use a queue to split the tokens and store them. Well this would grow dynamically.
After parsing whole input, the argv array is allocated
argc is the length of the queue
Memory allocation failures are handled though
The cleanup function is separated


Note: The implementation of queue is skipped for simplicity. Hope this program is self explanatory.