Q:

Fully dynamical string arrays in C

I am currently working on a very basic shell written in C. To do that, I need to be able to break down an input string into "words" so I can send it to execvep(). To do that, I created a function shishell() that expects a string of unknown lenght and that will internally maked an array of string. Since the size of the words and their quantity isn't known beforehand, the string array is fully dynamic.
The main problem I have it that this function works well for 1 or 2 "words" in a string, but as soon as I go beyond 3 "words" it starts breaking down, causing segmentation faults and double free corruptions errors.
Here is a test program :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

int main(int argc, const char *argv[])
{
    shishell(argv[1]);
    return 0;
}

int fakexec(char** e_input_arr) {
    int c = 0;
    while(*e_input_arr) {
        char* x = *e_input_arr++; c++;
        printf(" >%d - %s\n", c, x);
    }
}

int shishell(char* e_input) {
    int n = 0,
    cur_i = 0,
    cur_w = 0;
    char tmp;
    char** input = malloc(sizeof(char*));
    input[n] = malloc(sizeof(char));

    while ((tmp = e_input[cur_i]) == ' ') {
        cur_i++;
    }
    while ((tmp = e_input[cur_i]) != '\0') {
        switch (tmp) {
            case ' ':
                if (cur_i) {
                    if (e_input[cur_i-1] != ' ') {
                        n++;
                        input = realloc(input, (n+1) * sizeof(char));
                        input[n] = malloc(sizeof(char));
                    }
                }
                cur_w = 0; cur_i++;
                break;
            default:
                input[n] = realloc(input[n], sizeof(char)*cur_w+2);
                input[n][cur_w] = e_input[cur_i];
                input[n][cur_w+1] = '\0';
                cur_w++; cur_i++;
                break;
        }
        printf(">%d - '%c'\n", n, tmp);
    }
    printf("Pre execuction\n");
    fakexec(input);

    printf("Post execuction\n");

    int j;
        for (j = 0; j < n; j++)
        free(input[j]);
    free(input);
}

This program expects ONE string parameter.
And here are some exeample outputs :
% ./test test                              
>0 - 't'
>0 - 'e'
>0 - 's'
>0 - 't'
 >1 - test

% ./test "hello world" 
>0 - 'h'
>0 - 'e'
>0 - 'l'
>0 - 'l'
>0 - 'o'
>1 - ' '
>1 - 'w'
>1 - 'o'
>1 - 'r'
>1 - 'l'
>1 - 'd'
 >1 - hello
 >2 - world

Everything works well for those, but then :
% ./test "hello world foo"
>0 - 'h'
>0 - 'e'
>0 - 'l'
>0 - 'l'
>0 - 'o'
>1 - ' '
>1 - 'w'
>1 - 'o'
>1 - 'r'
>1 - 'l'
>1 - 'd'
>2 - ' '
>2 - 'f'
>2 - 'o'
>2 - 'o'
 >1 - hello
 >2 - world
 >3 - foo
zsh: segmentation fault (core dumped)  ./test "hello world foo"

I presume the problems may be comming from my calls to realloc, malloc and free however, I don't really what I'm doing wrong since I'm doing the realocations as I need them.

A:

Your fakexec function includes while(*e_input_arr).
This will only work properly if you include a null termination entry. However you don't do that so it reads off the end of the allocated space, causing a segmentation fault.
In fact, you don't allocate input properly. The line char** input = malloc(sizeof(char*)); only allocates space for input[0]. But you increment n and go on to access input[1] etc.

