指针变量存储大于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]
同时具有i
和j = 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 位 int
和 int 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));
如何写入我有 pnumber[2%4][2%4]
的 2D 指针,以及如何获得显示超过 3 个密码的 pnumber
?
我正在编写一个用 C 语言编写帕斯卡三角形的程序。
当指针pnumbers[i][j]
同时具有i
和j = 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 位 int
和 int 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));