[英]C Program crashes after entering a big value
我想拥有两个数组A
和B
,其中A=[a0, a1, a2, …, aN-1]
, B=[b0, b1, b2, …, bN-1]
其中“ N”将是来自用户。 我想用0到1之间的随机数填充两个数组。然后我想在数组C[n]
得到aN
和bN
的乘积,我也想对数组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);
由于sum
是double
,因此为printf
提供与格式说明符不匹配的变量类型是未定义的行为。 您很有可能会看到通配符被打印出来。 格式说明符%d
需要一个int
类型,而不是double
类型。 因此更正为:
printf("%lf", sum);
但是,由于您使用的是C ++,您应该只使用std::cout
,因为它是类型安全的,不会让您陷入此类麻烦:
std::cout << sum;
当您删除所有错误并进行更正描述时,这是一个显示输出的实时示例。
此外,这是一种使用STL算法函数的替代方法,该函数比您现在拥有的代码要短得多,并且不需要声明3个向量(只需声明一个向量):
如果数组的大小为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.