0
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;
}
bogconst
  • 33
  • 1
  • 7
  • Well for starters, allocating a single byte for `*words` is not enough space for an *array* of *pointers* (each being likely 4 or 8 bytes). And `sizeof(word)` will not tell you the size of the string, only the size of a `char*`. Keep in mind, `sizeof` calculations do not occur during runtime. – Taylor Brandstetter Oct 30 '14 at 18:15
  • You might like to enable your compiler's warnings (command line options `-Wall -Wextra -pedantic` for gcc), then fix your code until no more warnings are issued. – alk Oct 30 '14 at 18:17
  • Suggest `strlen(word)` rather than `sizeof(word)`. – chux - Reinstate Monica Oct 30 '14 at 18:26
  • Thank you: @TaylorBrandstetter the first problem was at `char` instead of `char*` when allocating memory; chux I changed `sizeof(...)` with `strlen(...)` an the size of the words is correctly allocated. – bogconst Oct 30 '14 at 18:41

2 Answers2

0
    *words = realloc(*words, ((*size) + 1) * sizeof(char));
    word = strtok(NULL, " \n\t");

The strtok function stashes a pointer to where it left off so it can resume when you pass a NULL as the first parameter. But your call to realloc invalidates the pointer it stored (because it can move the data). So you can't pass NULL as the first parameter. But you do.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
0

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.

ash
  • 4,867
  • 1
  • 23
  • 33