2

I have a problem I can't solve. I split a string in substrings and put these substrings in an array. Everything goes fine until the search function ends. the strtok function makes perfect substrings and then everything is nicely putten in the array but when the function ends the array loses all his content. I've tried a lot of different things but nothing seems to work. I want the words array to keep his content when the search function ends and returns to main.

int main(void)
{
    char** words=NULL;
    char argument[26] = "just+an+example";

    search(argument, words);
}

search(char* argument, char** words)
{
    char* p = strtok (argument, "+");
    int n_spaces = 0;

    while (p) 
    {
        words = realloc(words, sizeof(char*)* ++n_spaces);

        if (words == NULL)
            exit(-1); // memory allocation failed

        words[n_spaces-1] = p;
        p = strtok(NULL, "+");
    }

    // realloc one extra element for the last NULL 
    words = realloc(words, sizeof(char*)* (n_spaces+1));
    words[n_spaces] = 0;
}
Charles
  • 50,943
  • 13
  • 104
  • 142
  • Format your code with proper indentation, please. – OldProgrammer Mar 03 '14 at 19:05
  • 1
    You're not copying the data for the separate words, only saving pointers to the existing data split-up in-place. Which means those pointers will stop being valid when your source string goes out of scope, at which point the data might get overwritten etc. Could that be what's happening in your code? – Rup Mar 03 '14 at 19:07
  • @Rup So you say instead of words[n_spaces-1] = p I have to malloc for each words[n_spaces-1] and then strcpy p to words[n_space-1]? – user3376147 Mar 03 '14 at 19:14
  • 1
    If that's actually your problem, yes, although it'd be simpler to `strdup(argument)` and `strtok` the copy. (That's also simpler to `free` afterwards.) – Rup Mar 03 '14 at 19:18
  • 1
    C++ realloc works with a NULL pointer; C stdlib may not. Try initializing words to malloc(1) instead of NULL – mpez0 Mar 03 '14 at 19:19
  • @mpez0 C++ `realloc` *is* C `realloc`. – n. m. could be an AI Mar 03 '14 at 19:24

2 Answers2

1

I'm guessing that you want words in main to point to an array of pointers to the places where the delimiter is. You need to pass in the address of the variable words to search, and inside search, modify the memory pointed at by the variable words.

Try this:

int main(void)
{
   char** words = NULL;
   char argument[26] = "just+an+example";

   search(argument, &words);
}

search(char* argument, char*** words)
{
    char* p = strtok (argument, "+");
    int n_spaces = 0;

    while (p) 
    {
       *words = realloc(*words, sizeof(char*) ++n_spaces);

       if (*words == NULL)
            exit(-1); // memory allocation failed

        (*words)[n_spaces-1] = p;
        p = strtok(NULL, "+");
    }

    // realloc one extra element for the last NULL 
    *words = realloc(words, sizeof(char*)* (n_spaces+1));
    (*words)[n_spaces] = 0;
}

I didn't review your logic in search at all, so you may not be done debugging yet.

Lencho Reyes
  • 359
  • 3
  • 10
  • Hey @Lencho Reyes thanks for helping me. I figured it out. I had to use &words in the main but (*words)[n_spaces-1] = p does not work. I had to use malloc and strcpy to copy the string that p points to into words array – user3376147 Mar 03 '14 at 19:47
  • It could be that I misunderstood your original intent. Would you mind posting what did work for you as an answer? That way anyone who finds the question in the future will see how it's done. – Lencho Reyes Mar 03 '14 at 20:33
0

I was doing af few things wrong. First of all in the main function when I called the search function I had to pass the adress of my array (&words). My second mistake was instead of copying the substrings itself I copied the pointers to the substrings. At the end of the function these pointers are freed so my array lost his content at the end of the function. To fix this I had to malloc every time I wanted to copy a new string to my array and use strcpy to copy the string where the pointer points to to my array.

int main(void)
{
   char** words = NULL;
   char argument[26] = "just+an+example";

   search(argument, &words);
}

search(char* argument, char*** words)
{
   char* p = strtok (argument, "+");
   int n_spaces = 0;

   while (p) 
   {
      *words = realloc(*words, sizeof(char*) ++n_spaces);

      if (*words == NULL)
        exit(-1); // memory allocation failed

      (*words)[n_spaces - 1] = malloc(sizeof(char)* (strlen(p) + 1));

      strcpy((*words)[n_spaces - 1], p);

      p = strtok(NULL, "+");
   }

}