Search code examples
cmallocdynamic-memory-allocationreallocstrtok

How do I dynamically allocate memory for an array of strings in C?


I read the previous questions on dynamic arrays in C however I was not able to relate the answers to my question.

I am taking commands from stdin using fgets, removing the newline character and then want to store each command delimited by a space in a dynamically allocated array of strings. I however am having a lot of trouble with the correct way to allocated and reallocate memory. I am compiling with clang and keep getting segmentation fault 11. I then used -fsanitize=address and keep getting:

==2286==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000eeb8 at pc 0x000108fb6f85 bp 0x7fff56c49560 sp 0x7fff56c49558 WRITE of size 8 at 0x60200000eeb8 thread T0

Here is my code:

// Sets a delimiter to split the input
const char *seperator = " ";

char *token = strtok(line, seperator);

char **cmds = (char **) malloc(sizeof(char) * sizeof(*cmds));
// Adds first token to array of delimited commands
cmds[0] = token;

int count = 1;
while (token != NULL) {
    token = strtok(NULL, sep);
    if (token != NULL) {
        cmds = (char **) realloc(cmds, sizeof(char) * (count + 1));
        // Adds next token array of delimited commands
        cmds[count] = token;
        count++;
    }
}

Solution

  • You're not allocating enough memory. cmds is an array of pointers, so each element is sizeof(char *) bytes, not sizeof(char) bytes.

    On the initial allocation you want 1 char *, then on subsequent allocations you want count + 1.

    Also, don't cast the return value of malloc, as that can hide other problems, and don't forget to check for failures.

    char **cmds = malloc(sizeof(char *) * 1);
    if (cmds == NULL) {
        perror("malloc failed");
        exit(1);
    }
    ...
            cmds = realloc(cmds, sizeof(char *) * (count + 1));
            if (cmds == NULL) {
                perror("reallocfailed");
                exit(1);
            }