user2145240
user2145240

Reputation: 95

Allocate a 3D char array in C (char ***)

I would like to allocate a char***. I have a got a sentence like this: "This is a command && which I || need to ; split" I need to put in each box a full sentence just like that:

cmd[0] = "This is a command"
cmd[1] = "wich I"
cmd[2] = "need to"
cmd[3] = "split"

Sentences are separated by tokens like &&, ||, ;, |.
My problem is that I don't know how to allocate my triple dimension array. I always get a Segmentation Fault.

This is what I do :

for(k = 0; k < 1024; k++)
   for( j = 0; j < 1024; j++)
       cmd[k][j] = malloc(1024);

But a few line later, in an other loop :

»           cmd[k][l] = array[i];

I get a segfault here.

How can I do this please ? Thanks in advance

Upvotes: 0

Views: 3239

Answers (2)

Sergey L.
Sergey L.

Reputation: 22562

If you are going to be splitting your string by delimiters that are longer then a single character then this is how you could do it with string search.

The following function will accept an input string and a delimiter string. It will return a char ** which has to be freed and it will destroy your input string (reusing it's memory to store the tokens).

char ** split_string(char * input, const char * delim) {
    size_t num_tokens = 0;
    size_t token_memory = 16; // initialize memory initially for 16 tokens
    char ** tokens = malloc(token_memory * sizeof(char *));

    char * found;
    while ((found = strstr(input, delim))) { // while a delimiter is found
        if (input != found) { // if the strind does not start with a delimiter

            if (num_tokens == token_memory) { // increase the memory array if it is too small
                void * tmp = realloc(tokens, (token_memory *= 2) * sizeof(char *));
                if (!tmp) {
                    perror("realloc"); // out of memory
                }
                tokens = tmp;
            }

            tokens[num_tokens++] = input;
            *found = '\0';
        }
        // trim off the processed part of the string
        input = found + strlen(delim);
    }

    void * tmp = realloc(tokens, (num_tokens +1) * sizeof(char *));
    if (!tmp) {
        perror("realloc"); // something weird happened
    }
    tokens = tmp;

    // this is so that you can count the amount of tokens you got back
    tokens[num_tokens] = NULL;

    return tokens;
}

You will need to recursively run this to split by more then one delimiter.

Upvotes: 0

Sergey L.
Sergey L.

Reputation: 22562

Please keep in mind that a 2/3D array in C is not the same as a char ***.

If all you wish is to have a 1024^3 character array then you will be good with

char array[1024][1024][1024];

But keep in mind that this will allocate 1 GB of space on your stack which may or may not work.

To allocate this much on the heap you need to type it correctly:

char (*array)[1024][1024] = malloc(1024*1024*1024);

In this scenario array is a pointer to an array of 2D 1024x1024 character matrices.

If you really want to work with char *** (which I do not recommend if your array lengths are static) then you need to allocate all intermediary arrays too:

char *** cmd = malloc(sizeof(char **) * 1024);
for(k = 0; k < 1024; k++) {
    cmd[k] = malloc(sizeof(char *) * 1024);
    for( j = 0; j < 1024; j++)
           cmd[k][j] = malloc(1024);
}

Upvotes: 1

Related Questions