【问题标题】:Why is there not runtime error when accessing past the past-the-end element in C++? [duplicate]为什么在 C++ 中访问过去的结尾元素时没有运行时错误? [复制]
【发布时间】:2016-08-04 06:17:15
【问题描述】:

我有以下 C++ 示例代码,我的想法是它会在 LINE II 处引发运行时错误。

#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
void printer(int i) {
        cout << i << ", ";
}
int main() {
        int mynumbers1[]={3, 9, 0, 2};
        int mynumbers2[]={6, 1, 4, 5};
        vector<int> v1(7);
        sort(mynumbers2, mynumbers2 + 4);
        sort(mynumbers1, mynumbers1 + 4);//LINE I
        merge(mynumbers1, mynumbers1+5, mynumbers2, mynumbers2+5, v1.begin());//LINE II
        for_each(v1.begin(), v1.end(), printer);
        return 0;
}

然而程序的输出实际上是:

0, 1, 2, 3, 4, 5, 6, 

例如,如果我将合并的第二个参数更改为mynumbers1+6,则会出现运行时错误:

*** Error in `./program': free(): invalid next size (fast): 0x0000000002468010 ***
0, 1, 2, 3, 4, 5, 6, Aborted (core dumped)

我很惊讶,因为过去的元素是 mynumbers1+4,因此我预计 mynumbers1+5 会引发运行时错误。但显然情况并非如此。

我在 Ubuntu 虚拟机上使用 g++ (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4

谁能向我解释为什么没有抛出运行时错误?
这是未定义的行为吗?
它依赖于机器还是实现?
而且,最重要的是,为什么在一种“越界”的情况下会抛出运行时错误,而在另一种“越界”的情况下却没有抛出运行时错误?这个错误来自哪里?数组还是向量? 感谢您的宝贵时间

【问题讨论】:

  • 这个副本太多了
  • 查看std::array 以帮助进行边界检查。
  • 谢谢你们。但是说实话,这两个 cmets 都没有帮助我。我展示了两个“越界”的案例。在一种情况下存在运行时错误,而在另一种情况下,令人惊讶的是,没有运行时错误。你不觉得这令人困惑和不一致吗?我不认为它是重复的。另外,我指的是 C++ 而不是 C(它有自己的规范);请注意,我在示例中使用了 Vector。
  • @Elyasin 正如许多答案中所述,编译器不必检查 UB,也没有义务生成任何代码以使您的程序在 UB 中失败。所以你在这两种情况下都有UB,在一种情况下它可能会崩溃,而另一种情况可能不会。没有人会保证 UB 具有一致的行为。

标签: c++ arrays vector runtime-error


【解决方案1】:

C/C++ 不执行任何范围检查。这是因为存在性能损失。因此,访问超出其范围的数组是未定义的行为。任何事情都可能发生,包括数据损坏。认为自己很幸运,程序崩溃了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-09
    • 1970-01-01
    • 2013-01-16
    • 1970-01-01
    • 2020-10-03
    • 1970-01-01
    • 1970-01-01
    • 2015-08-05
    相关资源
    最近更新 更多