简体   繁体   中英

Segmentation Fault when using strtok

I get segmentation fault when using char *s in main. If I use char s[100] or something like that everything is ok. Why is that? SIGSEGV appears when i call find_short(char *s) function on line with instruction char *token = strtok(s, delim); . This is my code:

#include <sys/types.h>
#include <string.h>
#include <limits.h>
#include <stdio.h>

int find_short(char *s)
{
    int min = INT_MAX;
    const char delim[2] = " ";
    char *token = strtok(s, delim);
    while(token != NULL) {
        int len = (int)strlen(token);
        if (min > len)
            min = len;
        token = strtok(NULL, delim);
    }
    return min;
}
int main()
{
    char *s = "lel qwew dasdqew";
    printf("%d",find_short(s));
    return 0;
}

The line:

char *s = "lel qwew dasdqew";

creates a pointer to a constant string in memory.
Because that string is constant, you are unable to change its contents.
The strtok function will try to modify the contents by inserting \\0 at the token-delimiter locations, and will fail because the string cannot be modified.


Changing the line to:

 char s[] = "lel qwew dasdqew";

Now makes s an array of local data that you are free to change. strtok will now work because it can change the array.

The main your mistake is that you selected a wrong function to do the task.:)

I will say about this below.

As for the current program then string literals in C though they do not have constant character array types are immutable. Any attempt to change a string literal results in undefined behavior. And the function strtok changes passed to it string inserting the terminating zero between sub-strings.

Instead of the function strtok you should use string functions strspn and strcspn . They do not change the passed argument. So using these functions you are able to process also string literals.

Here is a demonstrative program.

#include <stdio.h>
#include <string.h>

size_t find_short( const char *s )
{
    const char *delim= " \t";

    size_t shortest = 0;

    while ( *s )
    {
        s += strspn( s, delim );

        const char *p = s;

        s += strcspn( s, delim );

        size_t n = s - p;

        if ( shortest  == 0 || ( n && n  < shortest ) ) shortest = n;
    }

    return shortest;
}

int main(void) 
{
    const char *s = "lel qwew dasdqew";

    printf( "%zu", find_short( s ) );

    return 0;
}

Its output is

3

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM