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

294 views Asked by At

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!

3

There are 3 answers

0
yano On BEST ANSWER

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;
}
4
user2736738 On

Allocate some memory in result. result=malloc(sizeof(char)*MAXLEN);

Now you are accessing some garbage value stored in result.

Accessing a uninitialized variable is Undefined Behavior.


  • Also you can allocate strlen(str)+1 as it you know no matter what the result can at most be as long as the str.

  • $7.20.3.1 Another point is that you can use calloc function for which the space is initialized to all bits zero.This has the benefit of always having a null terminated string , even if you accidentally omit nul-termination1

1. Pointed by David C. Rankin

2
Omniverse10 On

Basically what u are doing here is using a pointer which has no memory allocated .you need to allocate memory to result variable using malloc, for this u need to include stdlib.h

#include <stdio.h>
#include<stdlib.h>
#define MAXLEN 1000
unsigned char *startswith(unsigned char *str)
{
    char *result = malloc(sizeof(char)*MAXLEN);
    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;
}