C++ 用户输入可以超过数组的大小,但最终会崩溃,为什么?

C++ 用户输入可以超过数组的大小,但最终会崩溃,为什么?,c++,arrays,memory,reference,C++,Arrays,Memory,Reference,我允许用户输入数组的迭代次数。我试图了解当您超过最大大小10并输入一个高于该值的数字(如255)时会发生什么。然后,用户可以为每次迭代输入数字。该程序允许一些额外的输入,但在12或13点左右崩溃。为什么会这样?为什么程序不能允许指定的255次迭代?我认为它必须对C++中引用内存的方式做一些事情,但我不确定。 #include <iostream> using namespace std; int main() { int nums[20] = { 0 }; int a[10] =

我允许用户输入数组的迭代次数。我试图了解当您超过最大大小10并输入一个高于该值的数字(如255)时会发生什么。然后,用户可以为每次迭代输入数字。该程序允许一些额外的输入,但在12或13点左右崩溃。为什么会这样?为什么程序不能允许指定的255次迭代?我认为它必须对C++中引用内存的方式做一些事情,但我不确定。
#include <iostream> 
using namespace std;

int main()
{
int nums[20] = { 0 };
int a[10] = { 0 };

cout << a << endl;
cout << nums << endl;

cout << "How many numbers? (max of 10)" << endl;
cin >> nums[0];

for (int i = 0; i < nums[0]; i++)
{
 cout << "Enter number " << i << endl;
 cin >> a[i];
}

// Output the numbers entered
for (int i = 0; i < 10; i++)
    cout << a[i] << endl;

  return 0;
 }      
}
这:


仅当
i
介于0和9之间时有效。除此之外的任何值都是“未定义的行为”,这意味着程序可以做任何事情。包括前几次没有撞车,后来又撞车。包括立即坠毁。包括从不撞车。或者别的什么。它是未定义的。

您在代码中所做的是移动到数组a[]的有效范围之外。这将转到未定义的行为,正如您所经历的那样。即使您的程序在输入第12个数字后崩溃,即使转到[10]也是不正确的。未定义行为的真正含义是,不同机器的错误种类不同;另一台机器可能会在崩溃前达到[16],或者一台机器可能会简单而正确地停止并在[10]处崩溃。这就是为什么它被称为未定义行为;知道它迟早会崩溃,但看不到固定的模式

这种未定义的行为源于计算机的内存。每次重新运行程序时,都会在本地内存中为数组分配不同的内存块。这意味着周围的内存块可以被填充或未填充。因此,如果您的代码有错误,并且您将数组的索引扩展到其范围之外,那么如果接下来的几个内存字节为空且可访问,那么它可能会工作。然而,一旦它们到达一个完整的字节,或者如果该内存字节不可访问,则会导致程序崩溃。此外,由于该数组在内存中的位置可能会随着程序的重新运行而改变,因此在崩溃之前,它将走多远将完全取决于相邻的内存字节


这是一个很大的理论,所以如果我在这里出了什么差错,请让我知道。要进一步阅读,您可以访问

对此的简单回答是,您的程序正在尝试写入尚未分配的位。它将这样做,直到它尝试写入另一个进程正在使用的位为止。这就是使其崩溃的原因,因为此位不可用。在12或13左右,您似乎正在使用“已在使用中”。

未定义的行为,就这么简单。C++标准不保证你做这件事时会发生什么!您的代码甚至指定“多少个数字”不应超过10,因此您可能知道在数组边界之外写入是不好的。您的阵列大小为10。如果存储超过10个条目,则调用的是未定义的行为。你期望发生什么?
How many numbers? (max of 10)
255
Enter number 0
9
Enter number 1
9
Enter number 2
9
Enter number 3
9
Enter number 4
9
Enter number 5
9
Enter number 6
9
Enter number 7
9
Enter number 8
9
Enter number 9
9
Enter number 10
9
Enter number 11
9
Enter number 12
9
//(program crashes somewhere around here.)
int a[10] = { 0 };
cin >> a[i];