繁体   English   中英

输入较大的值后,C程序崩溃

[英]C Program crashes after entering a big value

我想拥有两个数组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  %.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优于数组的另一个领域。

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;

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

此外,这是一种使用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之类的智能指针和诸如std :: vector之类的STL容器。

除此之外,由于“ i <= c”,还超出了数组范围,因此还耗尽了堆栈空间:将数组放置在堆栈上,并且限制堆栈大小。 超出堆栈大小,程序将崩溃。 默认堆栈大小取决于OS和OS设置。 在Linux上,您可以使用“ ulimit -s”对其进行更改。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM