为什么这个新的 [ ] 和 delete [ ] 实现会因大于 12 的整数而失效?
Why does this new [ ] and delete [ ] implementation break down for integers > 12?
问题:我需要为作为命令行参数传递的任何(unsigned int)输入打印 Pascal 三角形。所有值都必须存储在线性数组中,并且元素只能作为取消引用的指针进行操作。在此之后,数组元素必须打印为下三角矩阵并随后删除。我的实现对于 0 到 12 范围内的输入完美运行,但对于更高的值会产生虚假结果。
我尝试了两种不同的实现方式。
声明一个指向大小为 (n+1)*(n+2)/2(这是输入 'n' 的三角形中的元素数)的数组的指针。 Assign/print 嵌套循环中的变量。执行完两个循环后删除指针。
运行 嵌套循环,0 <= i <= n,且 0 <= j <= i。在外循环中声明一个指向大小为 (i+1) 的数组的指针。 Assign/print 内循环中的元素。执行完内部循环后删除指针。
// VERSION 1
unsigned N = (n+1)*(n+2)/2;
unsigned* elements = new unsigned[N];
for(i = 0; i <= n; i++) {
for(j = 0; j <= i; j++) {
*(elements + j+(i*i+i)/2) = fact(i) / (fact(j) * fact(i-j));
// print statement
}
cout << endl;
}
delete [] elements;
// VERSION 2
for(i = 0; i <= n; i++) {
unsigned* elements = new unsigned[i+1];
for(j = 0; j <= i; j++) {
*(elements + j) = fact(i) / (fact(j) * fact(i-j));
// print statement
}
delete [] elements;
cout << endl;
}
这两个版本都在 Xcode 上分别试用过。在这两种情况下,三角形正确打印到第 12 层,即 n=12,但对于更高的值生成不正确的结果。
0 | 1
1 | 1 1
2 | 1 2 1
3 | 1 3 3 1
4 | 1 4 6 4 1
5 | 1 5 10 10 5 1
6 | 1 6 15 20 15 6 1
7 | 1 7 21 35 35 21 7 1
8 | 1 8 28 56 70 56 28 8 1
9 | 1 9 36 84 126 126 84 36 9 1
10 | 1 10 45 120 210 252 210 120 45 10 1
11 | 1 11 55 165 330 462 462 330 165 55 11 1
12 | 1 12 66 220 495 792 924 792 495 220 66 12 1
13 | 1 4 24 88 221 399 532 532 399 221 88 24 4 1
14 | 1 0 1 5 14 29 44 50 44 29 14 5 1 0 1
15 | 1 1 0 0 2 4 7 9 9 7 4 2 0 0 1 1
16 | 1 0 0 0 0 4 0 1 1 1 0 4 0 0 0 0 1
在我可以使用的范围内,调试器没有产生任何错误消息。
这是怎么回事,我该如何解决?
当i
为13时,fact(i)
为6227020800,32位无符号整数放不下,导致整数溢出
fact(i) 溢出非常快。我没有检查过这些数字,但我很确定这就是正在发生的事情。
相反,使用帕斯卡三角形中的数字是其上方两个数字之和的事实。
维基百科对此有 nice animation。
问题:我需要为作为命令行参数传递的任何(unsigned int)输入打印 Pascal 三角形。所有值都必须存储在线性数组中,并且元素只能作为取消引用的指针进行操作。在此之后,数组元素必须打印为下三角矩阵并随后删除。我的实现对于 0 到 12 范围内的输入完美运行,但对于更高的值会产生虚假结果。
我尝试了两种不同的实现方式。
声明一个指向大小为 (n+1)*(n+2)/2(这是输入 'n' 的三角形中的元素数)的数组的指针。 Assign/print 嵌套循环中的变量。执行完两个循环后删除指针。
运行 嵌套循环,0 <= i <= n,且 0 <= j <= i。在外循环中声明一个指向大小为 (i+1) 的数组的指针。 Assign/print 内循环中的元素。执行完内部循环后删除指针。
// VERSION 1
unsigned N = (n+1)*(n+2)/2;
unsigned* elements = new unsigned[N];
for(i = 0; i <= n; i++) {
for(j = 0; j <= i; j++) {
*(elements + j+(i*i+i)/2) = fact(i) / (fact(j) * fact(i-j));
// print statement
}
cout << endl;
}
delete [] elements;
// VERSION 2
for(i = 0; i <= n; i++) {
unsigned* elements = new unsigned[i+1];
for(j = 0; j <= i; j++) {
*(elements + j) = fact(i) / (fact(j) * fact(i-j));
// print statement
}
delete [] elements;
cout << endl;
}
这两个版本都在 Xcode 上分别试用过。在这两种情况下,三角形正确打印到第 12 层,即 n=12,但对于更高的值生成不正确的结果。
0 | 1
1 | 1 1
2 | 1 2 1
3 | 1 3 3 1
4 | 1 4 6 4 1
5 | 1 5 10 10 5 1
6 | 1 6 15 20 15 6 1
7 | 1 7 21 35 35 21 7 1
8 | 1 8 28 56 70 56 28 8 1
9 | 1 9 36 84 126 126 84 36 9 1
10 | 1 10 45 120 210 252 210 120 45 10 1
11 | 1 11 55 165 330 462 462 330 165 55 11 1
12 | 1 12 66 220 495 792 924 792 495 220 66 12 1
13 | 1 4 24 88 221 399 532 532 399 221 88 24 4 1
14 | 1 0 1 5 14 29 44 50 44 29 14 5 1 0 1
15 | 1 1 0 0 2 4 7 9 9 7 4 2 0 0 1 1
16 | 1 0 0 0 0 4 0 1 1 1 0 4 0 0 0 0 1
在我可以使用的范围内,调试器没有产生任何错误消息。
这是怎么回事,我该如何解决?
当i
为13时,fact(i)
为6227020800,32位无符号整数放不下,导致整数溢出
fact(i) 溢出非常快。我没有检查过这些数字,但我很确定这就是正在发生的事情。
相反,使用帕斯卡三角形中的数字是其上方两个数字之和的事实。
维基百科对此有 nice animation。