访问超出范围索引时导出异常数字

时间:2016-08-06 17:19:13

标签: c++ vector

下面的代码演示了在向量

中访问超出范围索引时的奇怪行为
#include <iostream>
#include <vector>

int main()
{
    std::vector<int> a_vector(10, 0);

    for(int i = 0; i < a_vector.size(); i++)
    {
        std::cout << a_vector[i] << ", ";
    }
    for(int j = 0; j <= a_vector.size(); j++)
    {
        std::cout << a_vector[i] << ", ";
    }
    return 0;
}

第一个for循环产生预期的0, 0, 0, 0, 0, 0, 0, 0, 0, 0,输出,但是第二个循环产生0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1318834149,

每次运行代码时,第二个循环产生的最后一个数字都会改变,并且总是很大,除非向量的长度在三到七之间(包括),在这种情况下,最后一个数字是0。持续存在更大的索引 - 例如,将第二个循环的停止值修改为j <= a_vector.size() + 2000会一直生成大数,直到索引1139,此时它将恢复为0.

这个数字来自哪里,它是否意味着什么,最重要的是为什么代码不会抛出“超出范围”的错误,这就是我要求它访问第11个元素时所期望的错误一个矢量10个元素长

2 个答案:

答案 0 :(得分:1)

你有意思吗?

for(int j = 0; j < a_vector.size(); j++)
{
    std::cout << a_vector[j] << ", ";
}

因为你已经离开了矢量范围,所以它是一个未定义的行为,并且每次运行它都会返回并且是“随机”数字。

答案 1 :(得分:0)

C ++功能强大,功能强大,责任重大。如果你超出范围,它会让你。 99.99999999%的时间不是好事,但它仍然允许你这样做。

至于为什么每次都改变,计算机在数组结束后将内存块视为另一个int,然后显示它。该int的值取决于该内存中最后一次使用的位数。它可能已用于程序中较早分配和丢弃的字符串,它可能是编译器在内存分配中插入以优化访问的填充,它可能是另一个对象使用的活动内存。如果你不知道(就像在这种情况下),你无法知道,也不应该期待任何一致的行为。

(什么是0.00000001%什么时候它是好事,你可能会问?一旦我故意超出子类中数组的范围来访问父类中没有访问者来修复bug的一些私有数据这是在一个我无法控制的库中,所以我不得不这样做或者接受这个bug。也许这不是一件好事,但由于我对那个特定情况下的内存布局很有信心,所以它起作用了。)< / p>

附录: 我提到的案例是对糟糕情况的务实解决方案。需要发布的代码和供应商几个月都不会修复错误。虽然我对这种行为充满信心(我知道确切的目标平台,代码是静态链接的,因此不会被用户替换等),这引入了代码脆弱性和未来的新责任。也就是说,下次更新库时,几乎肯定会破坏。

所以我评论了解释确切问题的代码,我正在做什么,什么时候应该删除。我在提交消息中也使用了大量的大写字母。我告诉所有其他程序员,以防我在修复bug之前被公共汽车撞到。换句话说,我行使了掌握这股强大力量所需的巨大责任。