为什么这个新的 [ ] 和 delete [ ] 实现会因大于 12 的整数而失效?

Why does this new [ ] and delete [ ] implementation break down for integers > 12?

问题:我需要为作为命令行参数传递的任何(unsigned int)输入打印 Pascal 三角形。所有值都必须存储在线性数组中,并且元素只能作为取消引用的指针进行操作。在此之后,数组元素必须打印为下三角矩阵并随后删除。我的实现对于 0 到 12 范围内的输入完美运行,但对于更高的值会产生虚假结果。

我尝试了两种不同的实现方式。

  1. 声明一个指向大小为 (n+1)*(n+2)/2(这是输入 'n' 的三角形中的元素数)的数组的指针。 Assign/print 嵌套循环中的变量。执行完两个循环后删除指针。

  2. 运行 嵌套循环,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