myArray[N] 其中 N = 1,000,000 returns 是一个错误,而 myArray[1,000,000] 不是

myArray[N] where N = 1,000,000 returns an error whereas myArray[1,000,000] doesn't

文件扩展名:.cpp

我有以下代码:

int main() {
    int N; cin >> N;
    int myArray[N];
    return 0;
}

如果我将 N 输入为 1,000,000,则在尝试 运行 该程序时出现错误。但是,当我将 myArray[N] 设置为 myArray[1000000] 时,它不会。为什么会这样?

发生这种情况是因为,在 C++ 中,必须在编译时知道用 array[N] 声明的静态数组的大小,因此您的错误可能是您的编译器告诉您他必须知道大小事先。如前所述,当您需要动态数组时使用 std::vector

int myArray[N]; 在 C++ 中无效。这种行为是在 C99 中引入的,但从未在 C++ 中引入,可能是因为为了使其正常工作,它会导致在幕后发生许多丑陋的事情,结果会降低生成的代码的效率。事实上,这个特性甚至在 C11 中被逆转,它的支持只是可选的,不再是强制性的。请改用 std::vector<int> 或您选择的任何类似标准容器。

静态数组的大小array[N]必须在编译时知道。

对动态数组使用std::vector

// Example program
#include <iostream>
#include <string>
#include <vector>

int main()
{
    int N; std::cin >> N;
    std::cout << N << std::endl;
    std::vector<int> myArray(N);
    std::cout << myArray.size() << std::endl;
    return 0;
}

首先,VLA(可变长度数组)是对 C++ 的扩展。编译器支持这一点,因为它们通常也支持在标准中具有此功能的 C。

第二个问题这个数组是在栈上分配的。 堆栈的大小非常有限。因此,当您的 N 具有非常大的价值时,应用程序可能会崩溃,因为堆栈会溢出。

在这种情况下,您应该使用 std::vector,它将在堆上分配数据。

问题是为什么静态数组大小的数组不会崩溃? 可能有几个原因。

  1. 编译器注意到未使用数组并根据 "As if" 规则删除数组。
  2. 编译器在编译时知道数组的大小,因此知道所需的堆栈大小。此信息可能会传播到链接器,并且应用程序会以比默认值更大的堆栈大小构建(在一个源代码应用程序的情况下,这可能是可能的)。免责声明:这是我的猜测,我没有以任何形式(通过测试或编译器文档)验证这一点,但我发现这个 证实了我的怀疑。

发生这种情况是因为必须在编译时知道静态数组的大小

强烈推荐使用std::vector instead of arrays for more flexibility, and safety (this is always the answer: Use a vector if possible). You may use std::vector::reserve to request capacity be at least the length you want it to be. Use std::vector::capacity查看当前容量

#include <iostream>
#include <vector>

int main () {
  std::vector<int> ivec;
  ivec.reserve(100);
  std::cout << ivec.capacity() << std::endl;
  return 0;
}

输出:

100

只有当您有非常好的理由更喜欢数组而不是向量时,您才可以动态分配数组。使用 std::shared_ptr 使这个过程更加安全和方便。这是按照您想要的方式完成的方式:

#include <iostream>
#include <memory>

int main () {
  int N;
  std::cin >> N;
  std::shared_ptr<int> arr_ptr (new int[N],  std::default_delete<int[]>());
  for (int i = 0; i != N; ++i) {
    arr_ptr.get()[i] = i * 2;
  }

  for (int i = 0; i != N; ++i) {
    std::cout << arr_ptr.get()[i] << std::endl;
  }
  return 0;
} 

输入:

10

输出:

0
2
4
6
8
10
12
14
16
18