1

I'm trying to make a function that splits a cstring into an array of words. Eg. if I send in "Hello world" then I'd get an array with two places where the 1st place has the element "Hello", second "world". I'm getting segmentation fault and I can't for the life of me figure out what seems to be wrong.

  • In the for-loop I am checking how many spaces there are, which determines how many words there are in total (spacing is always N-1, N = number of words). Then I tell the program to add 1 to the counter (Because of N-1).

  • I declare a char* array[] in order to keep each of the individual words seperated, not sure if I need counter+1 here (because of the \0?)

  • This is where the tricky part comes in. I use strtok to seperate each words (using " "). I then malloc each position of char*array[] so that it has enough memory to store the words. This is done until there are no more words to put in.

I would really appreciate it if someone could give me a hint of which part is causing the segmentation fault!

void split(char* s){

    int counter = 0;
    int pos = 0;

    for(int i=0; s[i]!='\0'; i++){
        if(s[i] == ' '){
            counter ++;
        }
    }
    counter += 1;

    char* array[counter+1];

    char *token = strtok(s, " ");

    while(token != NULL){
        array[pos] = malloc(strlen(token));
        strcpy(array[pos], token);
        token = strtok(NULL, " ");
        pos++;
    }
3
  • 1
    malloc(strlen(token)) --> malloc(strlen(token)+1) Commented Sep 6, 2016 at 21:12
  • in order to find where it fails, a) run under a debugger, b) use valgrind (If using linux) Commented Sep 6, 2016 at 21:18
  • c) just add print statements like a sane person Commented Sep 6, 2016 at 21:24

1 Answer 1

3

if I send in "Hello world" then I'd get an array with two places where the 1st place has the element "Hello", second "world".

No. You can't pass a string literal to that function. Because strtok() modifies its input. So, it'll attempt to modify string literal, resulting in undefined behaviour.

Be aware of the limitations of strtok(). From the man page of strtok():

   Be cautious when using these functions.  If you do use them, note
   that:

   * These functions modify their first argument.

   * These functions cannot be used on constant strings.

   * The identity of the delimiting byte is lost.

   * The strtok() function uses a static buffer while parsing, so it's
     not thread safe.  Use strtok_r() if this matters to you.

So, you need to pass a pointer to a modifiable memory location if you want to use strtok().


As BLUPIXY pointed out, your malloc() call doesn't allocate sufficient space. You need one more byte than the string length (for the terminating nul byte).

Sign up to request clarification or add additional context in comments.

5 Comments

Pass a pointer to a modifiable memory location? Could you give an example? I thought char* s (parameter) is already a pointer
For example: passing an array. char arr[] = "Hello world"; split(arr);
Ohhhh I see. I'll experiment with this then report back how it goes!
Man, thank you so much for the help! I was able to fix the problem by passing an array to the split function. Couple of questions: when you wrote "string literal" does that mean that I aren't able to write "split("hello world)" but instead I need to make an variable which stores the string in and then send the variable into the split() function?
char arr[] = "Hello world"; copies it. But if you had char *p = "hello world"; split(arr); you'll have exactly the same problem. So, it's not passing a variable that makes the difference but what you pass.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.