中止陷阱:6(计算长数阶乘)
Abort trap: 6 (Calculating a long number factorial)
我正在按照以下函数计算大数的阶乘 link,我想更多地了解为什么会发生某些事情...
#include<stdio.h>
#define MAX 10000
void factorialof(int);
void multiply(int);
int length = 0;
int fact[MAX];
int main(){
int num;
int i;
printf("Enter any integer number : ");
scanf("%d",&num);
fact[0]=1;
factorialof(num);
printf("Factorial is : ");
for(i=length;i>=0;i--){
printf("%d",fact[i]);
}
return 0;
}
void factorialof(int num){
int i;
for(i=2;i<=num;i++){
multiply(i);
}
}
void multiply(int num){
long i,r=0;
int arr[MAX];
for(i=0;i<=length;i++){
arr[i]=fact[i];
}
for(i=0;i<=length;i++){
fact[i] = (arr[i]*num + r)%10;
r = (arr[i]*num + r)/10;
//printf("%d ",r);
}
if(r!=0){
while(r!=0){
fact[i]=r%10;
r= r/10;
i++;
}
}
length = i-1;
}
我的问题是:
- MAX常量的真正含义是什么?更大或更小是什么意思?
- 我发现如果我有一个 MAX = 10000(如示例中所示),我最多可以计算 3250!如果我尝试使用 3251!我收到 'Abort trap: 6' 消息。为什么是这个数字?它来自哪里?
- 如果我使用标志 -m32 为 32 位机器编译这段代码会有什么不同? 运行 他会和 64 位的一样吗?
谢谢!
- MAX为
fact
和arr
中的元素个数;尝试访问索引 >= MAX 的元素是错误的。
- 错误消息通常特定于您正在使用的环境,您没有提供详细信息。
- 它们并不相同,但差异(例如,指针的大小)不应以任何可识别的方式影响此代码。
正如 Scott Hunter 指出的那样,MAX
是 fact
和 arr
数组中元素的最大数量,这意味着它是可以出现在程序用完 space.
之前的结果
请注意,代码仅在其数组声明中使用 MAX
。它没有在任何地方使用 MAX
来确定它是否正在尝试读取或写入超出这些数组末尾的内存。这是一件坏事™。您的 "Abort trap: 6" 错误几乎肯定会发生,因为试图计算 3251!正在这样做:使用 arr
和 fact
.
的过大索引
要查看给定阶乘所需的位数,您可以增加 MAX
(例如,增加到 20,000)并将 main
中现有的 printf
调用替换为类似这个:
printf("Factorial requires %d digits.\n", length + 1);
请注意,我使用 length + 1
是因为 length
本身并不是位数:相反,它是 fact
中包含最多的数组位置的索引-结果的有效数字。如果我尝试计算 3251!,输出为:
Factorial requires 10008 digits.
这比您在 fact
中的可用数字多了八位,默认 MAX
值为 10,000。一旦程序逻辑超出数组中分配的space,它的行为是不确定的。您碰巧看到错误 "Abort trap: 6."
有趣的是,这是我尝试计算 3250 时的输出!:
Factorial requires 10005 digits.
当 MAX
设置为 10,000 时,程序仍无法可靠地运行,所以您的程序计算出 3250 的事实!成功可能令人惊讶,但这就是未定义行为的本质:也许你的程序会产生正确的结果,也许它会崩溃,也许它会变得有自我意识并向俄罗斯的目标发射导弹 (because it knows that the Russian counterattack will eliminate its enemies over here) .像这样编码不是一个好主意。如果您的程序需要的 space 多于可用的数量以完成计算,它应该停止并显示适当的错误消息,而不是试图继续它正在做的事情。
我正在按照以下函数计算大数的阶乘 link,我想更多地了解为什么会发生某些事情...
#include<stdio.h>
#define MAX 10000
void factorialof(int);
void multiply(int);
int length = 0;
int fact[MAX];
int main(){
int num;
int i;
printf("Enter any integer number : ");
scanf("%d",&num);
fact[0]=1;
factorialof(num);
printf("Factorial is : ");
for(i=length;i>=0;i--){
printf("%d",fact[i]);
}
return 0;
}
void factorialof(int num){
int i;
for(i=2;i<=num;i++){
multiply(i);
}
}
void multiply(int num){
long i,r=0;
int arr[MAX];
for(i=0;i<=length;i++){
arr[i]=fact[i];
}
for(i=0;i<=length;i++){
fact[i] = (arr[i]*num + r)%10;
r = (arr[i]*num + r)/10;
//printf("%d ",r);
}
if(r!=0){
while(r!=0){
fact[i]=r%10;
r= r/10;
i++;
}
}
length = i-1;
}
我的问题是:
- MAX常量的真正含义是什么?更大或更小是什么意思?
- 我发现如果我有一个 MAX = 10000(如示例中所示),我最多可以计算 3250!如果我尝试使用 3251!我收到 'Abort trap: 6' 消息。为什么是这个数字?它来自哪里?
- 如果我使用标志 -m32 为 32 位机器编译这段代码会有什么不同? 运行 他会和 64 位的一样吗?
谢谢!
- MAX为
fact
和arr
中的元素个数;尝试访问索引 >= MAX 的元素是错误的。 - 错误消息通常特定于您正在使用的环境,您没有提供详细信息。
- 它们并不相同,但差异(例如,指针的大小)不应以任何可识别的方式影响此代码。
正如 Scott Hunter 指出的那样,MAX
是 fact
和 arr
数组中元素的最大数量,这意味着它是可以出现在程序用完 space.
请注意,代码仅在其数组声明中使用 MAX
。它没有在任何地方使用 MAX
来确定它是否正在尝试读取或写入超出这些数组末尾的内存。这是一件坏事™。您的 "Abort trap: 6" 错误几乎肯定会发生,因为试图计算 3251!正在这样做:使用 arr
和 fact
.
要查看给定阶乘所需的位数,您可以增加 MAX
(例如,增加到 20,000)并将 main
中现有的 printf
调用替换为类似这个:
printf("Factorial requires %d digits.\n", length + 1);
请注意,我使用 length + 1
是因为 length
本身并不是位数:相反,它是 fact
中包含最多的数组位置的索引-结果的有效数字。如果我尝试计算 3251!,输出为:
Factorial requires 10008 digits.
这比您在 fact
中的可用数字多了八位,默认 MAX
值为 10,000。一旦程序逻辑超出数组中分配的space,它的行为是不确定的。您碰巧看到错误 "Abort trap: 6."
有趣的是,这是我尝试计算 3250 时的输出!:
Factorial requires 10005 digits.
当 MAX
设置为 10,000 时,程序仍无法可靠地运行,所以您的程序计算出 3250 的事实!成功可能令人惊讶,但这就是未定义行为的本质:也许你的程序会产生正确的结果,也许它会崩溃,也许它会变得有自我意识并向俄罗斯的目标发射导弹 (because it knows that the Russian counterattack will eliminate its enemies over here) .像这样编码不是一个好主意。如果您的程序需要的 space 多于可用的数量以完成计算,它应该停止并显示适当的错误消息,而不是试图继续它正在做的事情。