一段程序引发的问题:
cpp
for (int i = 0; i <= s.length() - L; ++ i) {
string str = s.substr(i, L);
if (++ hash[str] == 2) {
res.push_back(str);
}
}
}
bash
terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::substr: __pos (which is 2) > this->size() (which is 1)
在C++中,当无符号数和有符号数进行减法运算时,通常有符号数会被转换为无符号数,然后进行无符号算术运算,结果也是一个无符号数。这是由C++的整数提升和算术转换规则所决定的,被称为 "usual arithmetic conversions"。
例如:
cpp
unsigned int a = 5;
int b = 10;
auto c = a - b;
在这个例子中,b
被转换为一个相应的无符号数,然后再与 a
相减。如果 b
的值足够大以至于在转换为无符号数时不会导致负数,那么得到的结果是正常的。但是如果 b
较大(例如在本例中的10),转换结果会是一个非常大的无符号数,因为无符号整数不能表示负数。这个转换是按照模运算的方式来处理的,即加上或减去足够大的2的幂次,使结果适合无符号类型的表示范围。
回到上面的代码段中,s.length()
是一个 size_t
类型,即无符号类型。当与 L
这个有符号整数做减法时,L
会被转换为 size_t
类型,然后执行减法操作,结果也是 size_t
类型。如果 s.length()
小于 L
,则会发生上述的整数环绕(underflow),导致计算出一个非常大的无符号数,从而导致循环条件错误地评估为 true
。