C ++ string.length()奇怪的行为

时间:2015-06-17 00:28:45

标签: c++ string int

我刚遇到一个非常奇怪的问题。我的功能很简单:

int strStr(string haystack, string needle) {

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

然后,如果我拨打strStr("", "a"),虽然haystack.length()-needle.length()=-1,但这不会返回0,您可以自己尝试...

2 个答案:

答案 0 :(得分:3)

这是因为.length()(和.size())返回size_t,这是一个unsigned int。你认为你得到一个负数,实际上它下溢回到size_t的最大值(在我的机器上,这是18446744073709551615)。这意味着你的for循环将循环遍历size_t的所有可能值,而不是像你期望的那样立即退出。

要获得所需的结果,您可以将大小显式转换为int s,而不是unsigned int s(请参阅aslgs答案),尽管对于长度足够的字符串可能会失败(足够过度/不足标准int

修改 以下评论中的两个解决方案:

  1. (Nir Friedman)不要在aslg的答案中使用int,而是包含标题并使用int64_t,这将避免上述问题。

  2. (rici)将你的for循环转换为for(int i = 0;needle.length() + i <= haystack.length();i ++){,通过重新排列等式避免一起减去所有问题,一起避免问题。

答案 1 :(得分:1)

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

length返回size_t,换句话说是unsigned int。给定字符串的大小,分别为0和1,当您计算差值时,它会下溢并成为unsigned int的最大可能值。 (对于4字节的存储,这大约是4.2亿,但可能是不同的值)

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

编译器将索引器i转换为unsigned int以匹配该类型。因此,您必须等到i大于unsigned int的最大可能值。它不会停止。

解决方案:

您必须将每个方法的结果转换为int,如此,

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