Search code examples
cfunctionimplementationstartswith

Make a StartsWith function in C getting "Segmentation fault", What's wrong?


I'm trying to make an startswith function which if i had a string consists of
"Hello I am kira"
will split into the first word
"Hello" Only

and I really tried my best to get it to this form

#include <stdio.h>
unsigned char *startswith(unsigned char *str)
{
    char *result;
    char *cstr = (char *)str;     
    for (int i=0; cstr[i] != ' '; i++)
       result[i] = cstr[i];
    return(result);
}

int main()
{
    printf("%s\n",startswith("What is your name momo?"));
    return 0;
}

which should print "in my imagination"

What

and an newline then exit with 0 but i get the unknown holy error when compiling

Segmentation fault

I can't understand why that happens or even locate the problem
gcc doesn't help or show me warnings

stdio.h header was just to print the result no more
I know there's a way to achieve this without using any standard libraries but i need leading

Thanks!


Solution

  • A bit deeper explanation of what's happening here... You are getting a segfault because you are dereferencing a pointer to memory your process doesn't own. Your char* result pointer is uninitialized, meaning it could have any kind of junk data in it. When you try result[i] = cstr[i], you are invoking undefined behavior (SO won't let me link their undefined behavior documentation anymore), which simply means that from this point forward execution of the program has unpredictable results. In your case, the UB manifests itself with a segfault, although it may not always.

    In order to initialize your pointer, you must allocate some space for it using malloc or one of its similar functions. You should also free your memory when you are done using it. Your program is so short, in this case it's not a huge deal (the OS will most certainly clean up any memory allocated to the process when it exits), but it's good to get in the habit.

    #include <stdio.h>
    #include <string.h>
    
    // this function shouldn't modify str (and in fact modifying a string
    // literal like you're passing in would be UB anyway), so make this
    // a const char*
    char *startswith(const char *str)
    {
        // sizeof(char) is defined as 1 in the standard, so you can leave it out of the malloc expression
        char *result = malloc(strlen(str)+1);  // Assuming str has at least 1 space, this will guarantee enough space for result
        if (result == NULL)   // make sure malloc returned some memory for you
        {
            // handle the error here how you want
            fprintf(stderr, "out of memory!\n");
            exit(-1);
        }
        // no need for cstr
        int i;  // move i out of the loop so it will be in scope after the loop
        for (i=0; str[i] != ' '; i++)
           result[i] = str[i];
        // NUL terminate your string
        result[i] = '\0';
    
        // "return" isn't a function, parenthesis unnecessary.
        return result;
    }
    
    int main(void)
    {
        // store the returned result to a variable so we can free it
        char* result = startswith("What is your name momo?");
        printf("%s\n", result);
        // clean up the memory
        free(result);
        return 0;
    }