Question

This is the code the linux kernel uses to strip leading and trailing whitespace on a string:

char *strstrip(char *s)
{
        size_t size;
        char *end;

        size = strlen(s);

        if (!size)
                return s;

        end = s + size - 1;
        while (end >= s && isspace(*end))
                end--;
        *(end + 1) = '\0';

        while (*s && isspace(*s))
                s++;

        return s;
}

Here I use it as such:

int main( void ){

    /* strip test*/
    char buffer2[60];
    char* testy2 = buffer2;
    testy2 = "       THING!      ";
    printf("The stripped string: \"%s\"\n",strstrip(testy2));
    return 0;
}

The program compiles fine but when executed it states:

Segmentation fault (core dumped)

Why is this happening?

Was it helpful?

Solution 2

testy2 = "       THING!      ";

sets testy2 to point to a string literal. This may exist in read-only memory so can't be written to by strstrip.

You need to either allocate memory for testy2

const char* s = "       THING!      ";
testy2 = malloc(strlen(s)+1);
strcpy(testy2, s);
....
free(testy2);

or, easier, just initialise buffer2 with the string you want to manipulate

char buffer2[] = "       THING!      ";
printf("The stripped string: \"%s\"\n",strstrip(buffer2

OTHER TIPS

During the assignment of testy2 (testy2 = " THING! ";), you make it point on static read-only memory.

But in your strstrip() function you are trying to modify it.

You can solve it by allocating testy2 dynamically using malloc for example :

testy2 = malloc( sizeof( "       THING!      " ) + 1 );
strcpy( testy2, s );

// But don't forget to free the memory at the end !
free( testy2 );

The line

testy2 = "       THING!      ";

isn't doing what you think it's doing. It's not copying " THING! " to buffer2. It is merely setting the pointer testy2 to point to a string literal " THING! ". Then when you call the strstrip() function, the function attempts to modify a string literal, which is undefined behavior. Hence the segmentation fault.

You probably want to use strcpy() instead of the assignment operator:

strcpy (testy2, "       THING!      ");

A string literal in your code is typically placed by the compiler into a read-only section of your program's memory space. When you assign testy2 = " THING! ";, you're setting testy2 to point to a string literal in static "read-only" memory. Then when you call strstrip() to modify that memory, you get a SIGSEGV, or whatever your platform calls it, at the point that strstrip() tries to write the nul char ('\0') because you can't write to memory whose attributes are set to "read-only". To get a copy of that string literal that you can modify, you could use strcpy() to make a copy of it, and call strstrip() on that copy. Of course to make a copy of it, you have to copy it into memory you own, which you could get from malloc(strlen(testy2)+1) or new char[strlen(testy2)+1], or as you've done in your original post, by creating a local allocation.

One thing to note is that strstrip() both 1) returns a pointer that may be different from the passed-in pointer, and 2) may alter the string at the memory passed to it. In your example, you're losing the returned pointer because you didn't assign it to anything... which isn't all that bad because you can get the same pointer address back by simply calling strstrip() on the original pointer again, but that would be a little inefficient if you needed the stripped string more than once. But be careful here... if you used malloc() or new to dynamically allocate space for your copy of the string literal (and assigned the returned address to a pointer, let's say testy2), then don't assign the return of strstrip() to that pointer, or else you can't later use the pointer to free the dynamically allocated memory! When you call free() or delete, you need to pass it the original pointer you got from malloc() or new, not the pointer you got back from strstrip().

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top