Arch1tect
Arch1tect

Reputation: 4281

C++ string.length() Strange Behavior

I just came across an extremely strange problem. The function I have is simply:

int strStr(string haystack, string needle) {

    for(int i=0; i<=(haystack.length()-needle.length()); i++){
        cout<<"i "<<i<<endl;
    }
    return 0;
}

Then if I call strStr("", "a"), although haystack.length()-needle.length()=-1, this will not return 0, you can try it yourself...

Upvotes: 1

Views: 384

Answers (2)

Sinkingpoint
Sinkingpoint

Reputation: 7634

This is because .length() (and .size()) return size_t, which is an unsigned int. You think you get a negative number, when in fact it underflows back to the maximum value for size_t (On my machine, this is 18446744073709551615). This means your for loop will loop through all the possible values of size_t, instead of just exiting immediately like you expect.

To get the result you want, you can explicitly convert the sizes to ints, rather than unsigned ints (See aslgs answer), although this may fail for strings with sufficient length (Enough to over/under flow a standard int)

Edit: Two solutions from the comments below:

  1. (Nir Friedman) Instead of using int as in aslg's answer, include the header and use an int64_t, which will avoid the problem mentioned above.

  2. (rici) Turn your for loop into for(int i = 0;needle.length() + i <= haystack.length();i ++){, which avoid the problem all together by rearranging the equation to avoid the subtraction all together.

Upvotes: 3

aslg
aslg

Reputation: 1974

(haystack.length()-needle.length())

length returns a size_t, in other words an unsigned int. Given the size of your strings, 0 and 1 respectively, when you calculate the difference it underflows and becomes the maximum possible value for an unsigned int. (Which is approximately 4.2 billions for a storage of 4 bytes, but could be a different value)

i<=(haystack.length()-needle.length())

The indexer i is converted by the compiler into an unsigned int to match the type. So you're gonna have to wait until i is greater than the max possible value for an unsigned int. It's not going to stop.

Solution:

You have to convert the result of each method to int, like so,

i <= ( (int)haystack.length() - (int)needle.length() )

Upvotes: 1

Related Questions