我想要两个数组AB,其中A=[a0, a1, a2, …, aN-1]B=[b0, b1, b2, …, bN-1],其中“N”是用户的输入。我想用0到1之间的随机数填充两个数组。然后我想在aN数组中获得bNC[n]的乘积,我也想对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  %.15f\n",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优于数组的另一个 Realm 。
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  %.15f\n",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;

当您删除所有错误并进行更正描述时,这是一个live example showing the output.

此外,这是一种使用STL算法函数的替代方法,该函数比您现在拥有的代码要短得多,并且不需要声明3个 vector (只需声明一个 vector ):

Example using STL algorithms

关于c++ - 输入大值后C程序崩溃,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40273030/

10-16 11:24
查看更多