指针变量在存储大于1024的整数并且某些地址似乎被锁定时溢出。在C中

问题描述 投票:1回答:1

如何在具有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的sipher的较高整数的点,它似乎溢出了-我看不到其背后的逻辑。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;
}
c pointers malloc integer-overflow
1个回答
1
投票

But row number 13 is still quite messed up.

代码正在发生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;


编辑:另一个错误:

我通过将所有位初始化为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;
}

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

pnumbers[i] = malloc(sizeof pnumbers[i][0] * (i+1));
© www.soinside.com 2019 - 2024. All rights reserved.