user2519193
user2519193

Reputation: 211

Why is this instance of strstr giving me segmentation faults?

Here is the full code

int count_substr(const char *str, const char *sub)
{
    char *ret;

    int a = 0; // used to tell where the pointer has moved to
    int count = 0;

    ret = strstr(str, sub);

    while (strstr(ret, sub) !=  NULL) {
        printf("The substring is: %s\n", ret);

        for (a = 0; a < strlen(sub); a++) {
            ret++;
        }

        printf("The substring after moving pointer is: %s\n", ret);
        count++;
    }

    return count - 1;  
}

I don't understand what's happening here, I'm not using the null pointer once

strstr(ret,sub) 

becomes null, so why is it giving me seg faults?

Valgrind would state that

Invalid read of size 1 and  Address 0x0 is not stack'd, malloc'd or (recently) free'd

Upvotes: 2

Views: 1645

Answers (2)

chqrlie
chqrlie

Reputation: 144810

You do not test if the initial call ret = strstr(str,sub); succeeds.

If it returns NULL, the next call strstr(ret,sub) will definitely invoke undefined behavior.

Furthermore, your code does not update ret correctly in the while loop, you must set ret to the first char past the match, not merely advance it by the length of the match. Here is a simpler version:

int count_substr(const char *str, const char *sub) {
    /* returns the number of non overlapping matches of sub in str */
    const char *ret = str;   
    int count = 0;

    if (ret && sub && *sub != '\0') {
        while ((ret = strstr(ret, sub)) != NULL) {
            ret += strlen(sub);
            count++;
        }
    }
    return count;
}

Upvotes: 6

4pie0
4pie0

Reputation: 29724

You should definitely check return value of strstr (man strstr (3)):

RETURN VALUE
       These functions return a pointer to the beginning
       of the located substring, or NULL if the substring is not found.

Upvotes: 0

Related Questions