微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 for 循环中使用 vec.size() 时出现运行时错误 关于问题的更新:

如何解决在 for 循环中使用 vec.size() 时出现运行时错误 关于问题的更新:

解决 codeforces 问题时,我必须制作一个大小为 1 的向量。另外,我需要从向量的倒数第二个元素迭代回来,所以我使用了以下技术来使用 for 循环。

for(int i = vec.size()-2; i > -1; i--){
    vec[i] = vec[i] + vec[i+1];
}

此技术在 codeforces 编译器中抛出 runtime error。 但是,通过预先计算使用向量的大小,它运行良好。 以下代码段运行成功。

int s = vec.size();
for(int i = s-2; i > -1; i--){
    vec[i] = vec[i] + vec[i+1];
}

有人能帮我理解这个现象吗?

PS:在解决问题的同时,我做到了

cout << vec.size()-2;

令我惊讶的是,输出结果是

18446744073709551615

当向量大小为 1 时。输出应该是 -1,对吗?这是显而易见的,还是其他什么。请解释。

解决方法

在这里,您尝试访问 vec[-1],这会导致超出范围的下标

尝试运行它并寻找输出:

for(int i = vec.size()-2; i >= -1; i--){
    cout << i << endl; // At some point will be -1
    vector<int>::size_type j = i; // Then this will be a very large unsigned number
    cout << j << endl; // On my machine it is 18446744073709551615
    //vec[i] = vec[i] + vec[i+1];
}

当您有 vec[-1] 时,-1 将被转换为 std::vector<T>::size_type,它是无符号的。这将导致 i 实际上是一个非常大的无符号数,进而导致通过下标进行错误访问。

另一个版本本质上是一样的,但它可能以某种方式执行,或者可能不会(例如,对我来说它并不顺利)。所有这一切都是因为这两种情况都是未定义行为的一个实例。

正如对您的问题的评论中所指出的,您可以查看 at() (do Recommendation)std::vector 成员函数或尝试对 out 进行显式检查范围下标自己。

关于问题的更新:

我建议您实施以下检查并在您的平台上运行它:

for(int i = vec.size()-2; i > -1; i--){
        auto a = vec[i];
        auto b = vec[i+1];
        std::cout << "i: " << i << "; " << "i+1: " << i+1 << std::endl;
        std::cout << "a:" << a << " + " << "b:" << b << " = "  << a+b  <<  std::endl;
        std::cout << std::endl;
        vec[i] = a + b;
    }

例如输入:std::vector<int> vec = {1,2,3,4,5};它给出以下输出:

i: 3; i+1: 4
a:4 + b:5 = 9

i: 2; i+1: 3
a:3 + b:9 = 12

i: 1; i+1: 2
a:2 + b:12 = 14

i: 0; i+1: 1
a:1 + b:14 = 15

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。