Search code examples
creallocsigabrt

C realloc() char ** "invalid next size" error


int parseString(char* input, char*** words, int* size) {
    char *word;

    *words = malloc(sizeof(char));
    word = strtok(input, " \n\t");

    while (word != NULL) {
        (*words)[*size] = malloc(sizeof(word) + 1);
        strcpy((*words)[*size], word);
        (*size)++;
        *words = realloc(*words, ((*size) + 1) * sizeof(char));
        word = strtok(NULL, " \n\t");
    }
    return 0;
}

I would like to receive a string (input) and split it in words and store the words.

On the forth iteration (always on the forth, never sooner) in the while loop I get a error at realloc(...):

realloc(): invalid next size: 0x0000000001641010 ***
Aborted (core dumped)

After making the suggested changed made by @TaylorBrandstetter and @chux the code looks like this:

int parseString(char* input, char*** words, int* size) {
    char *word;

    *words = malloc(sizeof(char*));
    word = strtok(input, " \n\t");

    while (word != NULL) {
        (*words)[*size] = malloc(strlen(word) + 1);
        strcpy((*words)[*size], word);
        (*size)++;
        *words = realloc(*words, ((*size) + 1) * sizeof(char*));
        word = strtok(NULL, " \n\t");
    }
    return 0;
}

Solution

  • The flaw is in the handling of strings:

    (*words)[*size] = malloc(sizeof(word) + 1);
    strcpy((*words)[*size], word);
    

    sizeof(word) is 4 (well, it may be something else, but it's the size of the pointer). This needs to be strlen(word) instead:

    (*words)[*size] = malloc(strlen(word) + 1);
    strcpy((*words)[*size], word);
    

    And, as @Taylor Brandstetter mentioned, the malloc for *words is too small. In fact, without knowing a maximum number of words in the input, it will be impossible to know the end size of *words until the input has been parsed once.