Search code examples
csplitdynamic-memory-allocationc-stringsfunction-definition

Returning pointer to char* ruins data


I am trying to write a function that will split a string along a space (' ') without changing the original string, put all of the tokens into an array, then return that array. The problem I am running into is in returning the pointer. Below is my code.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char **split_line(char *ln) {
    char **tokens, *tok, line[256];
    int j;

    strcpy(line, ln);

    tokens = calloc(64, sizeof(char*));
    for (int i = 0; i < 64; i++)
        tokens[i] = calloc(64, sizeof(char));

    tokens[0] = strtok(line, " ");
    for (j = 1; (tok = strtok(NULL, " ")) != NULL && j < 63; j++) 
        tokens[j] = tok;
    tokens[j] = NULL;

    return tokens;
}

int main(void) {
    char **cut_ln, *input;

    input = "Each word in this string should be an element in cut_ln.";
    cut_ln = split_line(input);

    printf("`%s`\n", input);
    for (int i = 0; cut_ln[i] != NULL; i++)
        printf("[%d]: `%s`\n", i, cut_ln[i]);

    return 0;
}

When run, this gives:

`This word in this string should be an element in cut_ln.`
[0]: `This`
[1]: `wo1`
[2]: `�={G+s`
[3]: `G+s`
[4]: `string`
[5]: ``
[6]: `0����`
[7]: `��`
[8]: ``
[9]: ``
[10]: ``

When I try to print the contents of tokens in the split_line function, it gives the expected result. However, when tokens is returned and assigned to a variable, and then printed, it gives the result above as demonstrated. What am I doing wrong?


Solution

  • When you return tokens, it contains the pointers returned from strtok, which are pointers into line. But line no longer exists at this point.

    You allocated memory and made the various elements of tokens point to that allocated memory. Don't overwrite those values with the values returned from strtok.