为什么我要使用substr调用out_of_range?

时间:2017-04-16 19:21:46

标签: c++

我正在研究竞争性的编程问题。我写了这个问题来计算“VK”子串的数量。

int count(string test) {
    int answer = 0;

    for (int i = 0; i <= test.size()-2; i++) {
        if (test.substr(i,2) == "VK")
            answer++;
    }

    return answer;
}

当我尝试将“V”作为参数时,为什么会收到此错误消息?

terminate called after throwing an instance of 'std::out_of_range'
what():  basic_string::substr: __pos (which is 2) > this->size() (which is 1)

for循环中的语句不应该执行,因为循环条件失败了吗?

1 个答案:

答案 0 :(得分:3)

  

for循环中的语句不应该执行,因为循环条件失败了吗?

是的,你是对的,但条件没有失败test.size()std::size_t,是一种实现定义的无符号类型。

这里的关键是它是 unsigned ,这意味着它可以在不调用未定义行为的情况下溢出。当您通过"V"时,test.size()1。然后,1 - 2等于-1,但这会溢出,因为无符号数不能取负数!结果是非常大数。

因此,循环执行的次数比您想象的要多很多,而且std::out_of_range异常来自:在第二次迭代中,您已经访问了索引1,这是超出范围(test的大小为1)。

您需要引入前置条件检查:

if (test.size() < 2)
    return 0;