C程序在输入一个大值后崩溃

C Program crashes after entering a big value

本文关键字:一个 崩溃 程序 输入      更新时间:2023-10-16

我想有两个数组AB,其中A=[a0, a1, a2, …, aN-1], B=[b0, b1, b2, …, bN-1],其中"N"将是来自用户的输入。我想用0到1之间的随机数填充这两个数组。然后我想在数组C[n]中得到aNbN的乘积,我还想要数组C中元素的总和。我不确定我做错了什么,但应用程序运行正常,直到我输入一个数字,如100,000作为N,如果我输入一些像这样的大数字,应用程序将崩溃。

下面是我的c++代码:'
int main(int argc, char **argv)
{
  long long int n;
  cout << "Hi, what do you want n to be?n";
  cin >> n;
  long long int c = n - 1;
  double A[c], B[c], C[c];
  srand(time(NULL));
  for (long long int i = 0; i <= c; i++) {
    A[i] = ((double) rand() / (double) (RAND_MAX));
    B[i] = ((double) rand() / (double) (RAND_MAX));
    C[i] = (double) A[i] * B[i];
    printf("%d  %.15fn",i, C[i]);
  }
  double sum = 0;
  for (long long int i = 0; i <= c; i++){
    sum += C[i];
  }
  printf("%d", sum);
  return 0;
}

有一个问题是:

double A[c], B[c], C[c];

这在c++中是无效的,因为数组必须有常量表达式来表示条目的数量。您正在使用由编译器提供的扩展,即可变长度数组 (VLA)。这个问题很可能是由于数组太大而耗尽了堆栈空间。

请使用c++中有效的格式,即std::vector:

long long int n;
cin >> n;
long long int c = n - 1;
std::vector<double> A(c), B(c), C(c);

但是,请注意std::vector仅限于std::vector::max_size()元素,因此您为n输入的值可能太大而无法存储元素。重新考虑是否要超越max_size()值。


另外,你正在访问越界的元素。这是使用std::vector优于数组的另一个地方。

for (long long int i = 0; i <= c; i++) {
    A.at(i) = ((double) rand() / (double) (RAND_MAX));
    B[i] = ((double) rand() / (double) (RAND_MAX));
    C[i] = (double) A[i] * B[i];
    printf("%d  %.15fn",i, C[i]);
}

您将看到,当i == c时,对A.at()的调用保证会抛出std::out_of_range异常,表示您已经超出了索引i的范围。数组不能以任何一致性报告这样的错误,因为超出数组的边界是未定义的行为(代码可能"工作",也可能崩溃,等等)。


还有一个问题,它是:

  printf("%d", sum);

由于sumdouble,给printf一个不匹配格式说明符的变量类型是未定义的行为。更有可能的是,您将看到打印出大量的数字。格式说明符%d需要int类型,而不是double。所以更正是这样的:

  printf("%lf", sum);

但是由于你使用的是c++,你应该简单地使用std::cout,因为它是类型安全的,不会让你陷入这种麻烦:

  std::cout << sum;

当您删除所有错误并进行描述的更正时,下面是显示输出的实时示例。

另外,这里有一个使用STL算法函数的替代方法,它比你现在的代码短得多,并且不需要声明3个向量(只需要声明一个向量):

使用STL算法的示例

当你有一个大小为c的数组时,你可以访问从0到c-1的元素,而不是c!

所以你的循环应该是
for (long long int i = 0; i < c; ++i)
不是

for (long long int i = 0; i <= c; ++i)

另外,对于较大的c,考虑使用堆内存而不是堆栈内存,例如使用

A = new double[c];
不是

double A[c];

进一步,熟悉智能指针,如std::unique_ptr和STL容器,如std::vector。

除了超出数组边界之外,由于"i<=c",您正在耗尽堆栈空间:数组被放置在堆栈上,堆栈上的大小是有限的。超过堆栈大小将导致程序崩溃。默认堆栈大小取决于操作系统和操作系统设置。在Linux上,您可以使用"ulimit -s"来更改它。