指针变量存储大于1024的整数时溢出,有些地址好像是locked.in C

The pointer variables overflows when they store integers larger than 1024 and some adresses seem to be locked.in C

如何写入我有 pnumber[2%4][2%4] 的 2D 指针,以及如何获得显示超过 3 个密码的 pnumber

我正在编写一个用 C 语言编写帕斯卡三角形的程序。 当指针pnumbers[i][j]同时具有ij = 2 mod 4时,除了i和j = 2时,我的程序不会写入地址并给出错误信息:

pascals triangle: malloc.c:2406: sysmalloc: Assertion '{old_top == initial_top (av) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
Aborted.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int factorial(int p) {
    if (p>=1) {
        return p*factorial(p-1);
    }
    else {
        return 1;
    }
}

int NchooseM(int n, int m) {
    return factorial(n)/(factorial(n-m)*factorial(m));
}

int main() {

    int n =7;
    int x = n-2;
    int i, j, k;
    /*
    printf("How many rows of Pascals triangle do you want to write?\n");
    scanf("%d", &n);
    */
    int **pnumbers;
    pnumbers = (int **) malloc(n  *sizeof(int *));

    /* Allocate memory for storing the individual elements in a row */
    for (i = 0; i < n; i++) {
        pnumbers[i] = (int *) malloc(i * sizeof(int));
    }

    pnumbers[0][1] = 1;

    /* Calculating the value of pnumbers[k][l] */
    for (i = 0; i < n; i++) {

        for (j = 0; j <= i; j++) {
            pnumbers[i][j] = NchooseM(i,j);
        }

/*
        if (!(i % 4 == 2 && i != 2))
            for (j = 0; j <= i; j++) {
                pnumbers[i][j] = NchooseM(i,j);

        } else if (i > 2) {
            for (j = 0; j <= i-1; j++) {
                pnumbers[i][j] = NchooseM(i,j);
        }
        }
*/
    }

    /* Writing out the triangle */
    for (i = 0; i < n; i++) {
        for (k = 0; k <= x; k++){
            printf(" ");
        }
        for (j = 0; j <= i; j++) {
            printf("%d ", pnumbers[i][j]);
        }
        x = x-1;
        printf("\n");
    }
    for (i = 0; i < n; i++) {
        free(pnumbers[i]);
    }
    free(pnumbers);
  return 0;
}

当我避免写入这些地址并只是将它们打印出来时,我在这些内存地址处得到了一些看似随机的整数。 此外,当避免使用这些地址并打印出如此多的行时,我得到了一些具有更高整数且超过 3 个 siphers 的点,它似乎溢出了 - 我没有看到它背后的逻辑。 The result of running the second code

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int factorial(int p) {
    if (p>=1) {
        return p*factorial(p-1);
    }
    else {
        return 1;
    }

}

int NchooseM(int n, int m) {
    return factorial(n)/(factorial(n-m)*factorial(m));
}

int main() {

    int n =20;
    int x = n-2;
    int i, j, k;
    /*
    printf("How many rows of Pascals triangle do you want to write?\n");
    scanf("%d", &n);
    */
    int **pnumbers;
    pnumbers = (int **) malloc(n  *sizeof(int *));

    /* Allocate memory for storing the individual elements in a row */
    for (i = 0; i < n; i++) {
        pnumbers[i] = (int *) malloc(i * sizeof(int));
    }

    pnumbers[0][1] = 1;

    /* Calculating the value of pnumbers[k][l] */
    for (i = 0; i < n; i++) {
        /*
        for (j = 0; j <= i; j++) {
            pnumbers[i][j] = NchooseM(i,j);
        }
        */

        if (!(i % 4 == 2 && i != 2))
            for (j = 0; j <= i; j++) {
                pnumbers[i][j] = NchooseM(i,j);

        } else if (i > 2) {
            for (j = 0; j <= i-1; j++) {
                pnumbers[i][j] = NchooseM(i,j);
        }
        }
    }

    /* Writing out the triangle */
    for (i = 0; i < n; i++) {
        for (k = 0; k <= x; k++){
            printf(" ");
        }
        for (j = 0; j <= i; j++) {
            printf("%d ", pnumbers[i][j]);
        }
        x = x-1;
        printf("\n");
    }

    for (i = 0; i < n; i++) {
        free(pnumbers[i]);
    }

    free(pnumbers);

  return 0;
}

代码正在经历 int 溢出,因此出现 未定义行为 (UB)。

对于 32 位 intint factorial(int p)p > 12 溢出 int 范围。

代码可以使用更宽的整数类型(long long 可以达到 p==20),但可以在 NchooseM() 处进行改进以避免更高值的溢出。

类似于下面的内容。工作到 int n = 30;

int NchooseM(int n, int m) {
  // return factorial(n)/(factorial(n-m)*factorial(m));
  int nm = 1;
  int den = 1;
  for (int i = m+1; i <= n; i++) {
    assert(INT_MAX/i >= nm);
    nm *= i;
    assert(nm % den == 0);
    nm /= den++;
  }
  return nm; 
}

尝试了 unsigned long long 并达到了 int n = 62;


编辑:另一个错误:

我 "fixed" 通过将所有初始化为 1,但我怀疑 /* Calculating the value of pnumbers[k][l] */ for (i = 0; i < n; i++) { 代码中仍有问题。

pnumbers[i] = malloc((i + 1) * sizeof pnumbers[i][0]);
for (int j = 0; j < i + 1; j++) {
  pnumbers[i][j] = 1;
}

旁白:而不是 pnumbers[i] = (int *) malloc((i+1) * sizeof(int));,请考虑下面没有不必要的强制转换,也没有尝试匹配正确的类型。

pnumbers[i] = malloc(sizeof pnumbers[i][0] * (i+1));