C++ string.length() 奇怪的行为
C++ string.length() Strange Behavior
我刚遇到一个非常奇怪的问题。我的功能很简单:
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
,这不会return0,你可以自己试试...
这是因为.length()
(和.size()
)returnsize_t
,这是一个unsigned int。你认为你得到一个负数,而实际上它下溢回 size_t
的最大值(在我的机器上,这是 18446744073709551615)。这意味着您的 for 循环将遍历 size_t 的所有可能值,而不是像您期望的那样立即退出。
为了得到你想要的结果,你可以显式地将大小转换为 int
s,而不是 unsigned int
s(见 aslgs 答案),尽管对于足够长的字符串这可能会失败(足够over/under流一个标准int
)
编辑:
以下评论中的两个解决方案:
(Nir Friedman) 不要像 aslg 的答案那样使用 int
,而是包含 header 并使用 int64_t,这将避免上述问题.
(rici) 将您的 for 循环变成 for(int i = 0;needle.length() + i <= haystack.length();i ++){
,通过重新排列方程以避免一起减法来一起避免问题。
(haystack.length()-needle.length())
length
returns a size_t
,换句话说,一个无符号整数。给定字符串的大小,分别为 0 和 1,当您计算差值时,它会下溢并成为 unsigned int 的最大可能值。 (对于 4 个字节的存储,这大约是 42 亿,但可能是不同的值)
i<=(haystack.length()-needle.length())
索引器i
被编译器转换成unsigned int来匹配类型。所以你将不得不等到 i
大于 unsigned int 的最大可能值。它不会停止。
解决方案:
你必须把每个方法的结果都转换成int,像这样,
i <= ( (int)haystack.length() - (int)needle.length() )
我刚遇到一个非常奇怪的问题。我的功能很简单:
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
,这不会return0,你可以自己试试...
这是因为.length()
(和.size()
)returnsize_t
,这是一个unsigned int。你认为你得到一个负数,而实际上它下溢回 size_t
的最大值(在我的机器上,这是 18446744073709551615)。这意味着您的 for 循环将遍历 size_t 的所有可能值,而不是像您期望的那样立即退出。
为了得到你想要的结果,你可以显式地将大小转换为 int
s,而不是 unsigned int
s(见 aslgs 答案),尽管对于足够长的字符串这可能会失败(足够over/under流一个标准int
)
编辑: 以下评论中的两个解决方案:
(Nir Friedman) 不要像 aslg 的答案那样使用
int
,而是包含 header 并使用 int64_t,这将避免上述问题.(rici) 将您的 for 循环变成
for(int i = 0;needle.length() + i <= haystack.length();i ++){
,通过重新排列方程以避免一起减法来一起避免问题。
(haystack.length()-needle.length())
length
returns a size_t
,换句话说,一个无符号整数。给定字符串的大小,分别为 0 和 1,当您计算差值时,它会下溢并成为 unsigned int 的最大可能值。 (对于 4 个字节的存储,这大约是 42 亿,但可能是不同的值)
i<=(haystack.length()-needle.length())
索引器i
被编译器转换成unsigned int来匹配类型。所以你将不得不等到 i
大于 unsigned int 的最大可能值。它不会停止。
解决方案:
你必须把每个方法的结果都转换成int,像这样,
i <= ( (int)haystack.length() - (int)needle.length() )