for循环为什么能够循环haystack.length()次?

问题遇到的现象和发生背景

这个是在刷leetcode题中遇到的c++语法问题,在strStr函数的for循环中,i <= (haystack.length() - needle.length())应该一次循环都不执行才符合逻辑。
但却执行了haystack.length()次。请问内部是什么原因呢?

问题相关代码,请勿粘贴截图
#include
#include

using namespace std;

int strStr(string haystack, string needle) {
    if(needle.length() == 0) return 0;
    int n = haystack.length() - needle.length();
    // cout << n << endl;
    for(int i = 0; i <= (haystack.length() - needle.length()); i++)
    {
        cout << i << endl;
        if(haystack.substr(i, needle.length()) == needle)
            return i;
    }
    return -1;
}

int  main()
{
    string a = "aaaaa";
    string b = "aaaaaaaaaaa";
    strStr(a, b);
    return 0;
}

运行结果及报错内容
0
1
2
3
4
5
6
terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::substr: __pos (which is 6) > this->size() (which is 5)

因为length()函数返回的是无符号整型,两个无符号整型相减,默认结果还是无符号整型,所以i<=两个无符号整型相减的结果,是成立的。
两个字符串长度相减后是一个很大的整数,所以当循环到超过第一个字符串长度时,substr函数会崩溃

好像是因为(haystack.length() - needle.length())这个相减的值不对,我64位系统打印出来是18446744073709551610(但不知道是为什么),
如果是这个值,访问haystack肯定是要越界的,把(haystack.length() - needle.length())改为n好像就可以了。
测试代码如下:

C++ String length()实例讲解 - 码农教程
C++string类中substr()函数的使用方法_&Mr.Gong的博客-CSDN博客_c++ string substr

#include <iostream>
#include <limits.h>
 
using namespace std;
 
int strStr(string haystack, string needle) {
    if(needle.length() == 0) return 0;
    int n = haystack.length() - needle.length();
    long long ln = haystack.length() - needle.length();
    cout<<"ln="<<ln<<endl;
    //cout<<"MAX_INT="<<INT_MAX<<endl; 
     cout << "n="<<n <<",haystack.length()= "<<haystack.length()<<",needle.length()="<< needle.length()<<endl;
     
     cout<<"(haystack.length() - needle.length())="<<(haystack.length() - needle.length())<<endl;
     
    for(int i = 0; i <= n; i++)
    {
        cout << i << endl;
        if(haystack.substr(i, needle.length()) == needle)
            return i;
    }
    return -1;
}
 
int  main()
{
    string a = "aaaaa";
    string b = "aaaaaaaaaaa";
    int i = strStr(a, b);
    cout<<"i="<<i<<endl;
    return 0;
}
 

img

无符号整数相减,结果不可能是负数,所以溢出了