为什么C++中的操作系统/编译器依赖于溢出? 我有一个关于C++数组的问题。我正在学习C++,在数组中我遇到了一些我不理解的东西。

为什么C++中的操作系统/编译器依赖于溢出? 我有一个关于C++数组的问题。我正在学习C++,在数组中我遇到了一些我不理解的东西。,c++,arrays,C++,Arrays,假设我们有一个包含5个元素的整数数组。讲师说,在下一行中,如果我们试图获取数组第五个索引的输入,我们无法知道会发生什么,例如崩溃之类的,因为它依赖于操作系统和编译器 int testArray[5] {0}; std::cin >> testArray[5]; 你能告诉我为什么这种情况依赖于操作系统/编译器吗?数组不能在外部索引。C++做出了不实际检查这些索引的决定,这意味着可以读取数组的边界。它只是告诉您不应该这样做,并将越界检查委托给程序员以提高速度 由于编译器、操作系统和许多

假设我们有一个包含5个元素的整数数组。讲师说,在下一行中,如果我们试图获取数组第五个索引的输入,我们无法知道会发生什么,例如崩溃之类的,因为它依赖于操作系统和编译器

int testArray[5] {0};
std::cin >> testArray[5];

你能告诉我为什么这种情况依赖于操作系统/编译器吗?

数组不能在外部索引。C++做出了不实际检查这些索引的决定,这意味着可以读取数组的边界。它只是告诉您不应该这样做,并将越界检查委托给程序员以提高速度


由于编译器、操作系统和许多其他因素都可以决定内存的布局,因此读取数组的边界基本上可以做任何事情,包括提供垃圾值、分段错误处理,或者。

数组不应该在外部索引。C++做出了不实际检查这些索引的决定,这意味着可以读取数组的边界。它只是告诉您不应该这样做,并将越界检查委托给程序员以提高速度


由于编译器、操作系统和许多其他因素都可以决定内存的布局,因此读取数组的边界基本上可以做任何事情,包括提供垃圾值、分段错误处理或其他操作。

C++是一种系统语言。它不要求对操作进行任何检查:正确执行的程序将受到不必要的检查的阻碍,例如,验证阵列访问是否在范围内。检查将由每次访问可能需要的条件组成,除非优化器可以看到某些检查可以省略,并且可能还有额外的内存,因为系统需要表示检查数组的大小

由于没有检查,您可能会在分配给相关数组的内存之外处理字节。这可能会覆盖用于其他内容的值,也可能会访问超出页面边界的内存。在后一种情况下,系统可能设置为导致分段故障。在前一种情况下,它可以访问其他未使用的内存,并且可能没有不良影响。。。或者,它可能以某种方式修改堆栈,阻止程序从函数正确返回。然而,堆栈的布局取决于许多方面,如所使用的CPU、给定系统上的调用约定、一些编译器首选项。为了避免妨碍正确的程序,在执行非法操作时,没有强制行为。相反,程序的行为变得未定义,任何事情都可以发生


如果行为未定义是你造成的,那就有点不好了。简单的解决办法是不要造成未定义的行为是的,我知道,说起来容易做起来难。然而,不定义行为通常是很好的性能,它还允许不同的实现实际定义行为来做一些有用的事情。例如,它使得实现检查未定义的行为并报告这些情况是合法的。做一些事情来检测未定义的行为,例如,由一些编译器提供的-fsanitize=undefined完成。我认为这不会导致检测到所有类型的未定义行为,但它肯定会检测到某些类型的未定义行为。

C++是一种系统语言。它不要求对操作进行任何检查:正确执行的程序将受到不必要的检查的阻碍,例如,验证阵列访问是否在范围内。检查将由每次访问可能需要的条件组成,除非优化器可以看到某些检查可以省略,并且可能还有额外的内存,因为系统需要表示检查数组的大小

由于没有检查,您可能会在分配给相关数组的内存之外处理字节。这可能会覆盖用于其他内容的值,也可能会访问超出页面边界的内存。在后一种情况下,系统可能设置为导致分段故障。在前一种情况下,它可以访问其他未使用的内存,并且可能没有不良影响。。。或者,它可能以某种方式修改堆栈,阻止程序从函数正确返回。然而,堆栈的布局取决于许多方面,如所使用的CPU、给定系统上的调用约定、一些编译器首选项。为了避免妨碍正确的程序,在执行非法操作时,没有强制行为。相反,程序的行为变得未定义,任何事情都可以发生

如果行为未定义是你造成的,那就有点不好了。简单的解决办法是不要造成未定义的行为是的,我知道,说起来容易做起来难。然而
r、 保持行为未定义通常是良好的性能,它还允许不同的实现实际定义行为以做一些有用的事情。例如,它使得实现检查未定义的行为并报告这些情况是合法的。做一些事情来检测未定义的行为,例如,由某些编译器提供的-fsanitize=undefined完成。我认为这不会导致检测到所有类型的未定义行为,但它肯定会检测到某些类型的未定义行为。

我们确实不知道会发生什么,但它不依赖于操作系统或编译器。根据定义,简单地说,无法预测会发生什么。因为强制某些特定的行为会迫使编译器生成代码来检查数组溢出,这会使C++程序慢下来。C++在很久以前就做出了决定,如果你愿意的话,你有责任检查这些东西。@弗兰·奥斯安德利:这根本不是定义。如果X是可预测的,这是x的一个性质。如果X是不可预测的,这是X的一个属性。如果我们的X必须是可预测的,或者X必须是不可预测的,那么我们就声明了X的要求。C++标准中未定义的定义是“这个国际标准没有规定的行为。”该标准并没有说未定义的行为是可预测的,或者说未定义的行为是不可预测的。如果说这个定义意味着某些东西是不可预测的,那就错了。仅供参考,对于数组,这个术语是不受限制的。“溢出”一词通常指的是超出其范围的递增数字。确实,我们不知道会发生什么,但它不依赖于操作系统或编译器。根据定义,简单地说,无法预测会发生什么。因为强制某些特定的行为会迫使编译器生成代码来检查数组溢出,这会使C++程序慢下来。C++在很久以前就做出了决定,如果你愿意的话,你有责任检查这些东西。@弗兰·奥斯安德利:这根本不是定义。如果X是可预测的,这是x的一个性质。如果X是不可预测的,这是X的一个属性。如果我们的X必须是可预测的,或者X必须是不可预测的,那么我们就声明了X的要求。C++标准中未定义的定义是“这个国际标准没有规定的行为。”该标准并没有说未定义的行为是可预测的,或者说未定义的行为是不可预测的。如果说这个定义意味着某些东西是不可预测的,那就错了。仅供参考,对于数组,这个术语是不受限制的。“溢出”一词通常指的是递增超过其范围的数字。