已解决:
我觉得很蠢 . GMP很好,这是我的疏忽 . 使用 size_t mpz_sizeinbase (const mpz_t op, int base)
后,我意识到我用来复制结果的char数组太小了 . 增加它的大小解决了它 . 谢谢您的帮助!
我的任务是编写一个C程序,它计算从第1024个元素到第1048576个元素的斐波纳契数列的元素(从2的10次幂到2的20次幂,增加2的幂) . 为此,我'm using GMP library to handle the numbers. The problem is, that around the 17th power of 2, the number is so big, that even GMP can't处理它,这意味着我应该使用 malloc() .
这是我的 main() (我修改了粘贴的代码,取出了不必要的部分,如写入文件和时间测量,将用于程序的另一部分):
int main(){
int powersOfTwo[11];
char res[10000];
char *c;
c = res;
for(int i = 0; i < 11; i++){
powersOfTwo[i] = normalPower(2,i+10);
}
for(int i = 0; i < 11; i++){
fibo(c, powersOfTwo[i]);
printf("The %d th element of Fibonacci is %s\n",powersOfTwo[i],res);
memset(res, 0, sizeof res);
}
return 0;
}
现在这里是简单的 normalPower 函数(为了清楚起见,与问题没有任何关系):
int normalPower(int n1, int n2){
if(n2 == 0){
return 1;
}else{
int temp = n1;
for(int i = 1; i < n2; i++){
temp *= n1;
}
return temp;
}
}
现在问题, fibo 功能:
void fibo(char *c, int n){
mpz_t *fib1;
mpz_t *fib2;
mpz_t *temp;
fib1 = (mpz_t *) malloc(101000000 * sizeof(mpz_t));
fib2 = (mpz_t *) malloc(101000000 * sizeof(mpz_t));
temp = (mpz_t *) malloc(101000000 * sizeof(mpz_t));
if (NULL == fib1 || NULL == fib2 || NULL == temp){
printf("ERROR: Out of memory\n");
}
mpz_init(*fib1);
mpz_init(*fib2);
mpz_init(*temp);
mpz_set_str(*fib1,"0",10);
mpz_set_str(*fib2,"1",10);
int i;
if(n == 0){
char *d = mpz_get_str(NULL,10,*fib1);
strcpy(c,d);
}
if(n == 1){
char *d = mpz_get_str(NULL,10,*fib2);
strcpy(c,d);
}
if(n > 1){
for(i = 1; i < n; i++){
mpz_set(*temp, *fib2);
mpz_add(*fib2, *fib1, *fib2);
mpz_set(*fib1,*temp);
}
char *d = mpz_get_str(NULL,10,*fib2);
strcpy(c,d);
}
free(fib1);
free(fib2);
free(temp);
}
最初我只使用mpz_t-s,启动它们和mpz_clear() - 它们最后没有指针和malloc(),但是在计算了17(-ish)元素的幂之后导致了 Segmentation fault (core dumped) 错误 . 这是我在互联网上找到的解决方案,这几乎是我可以分配的最大数字,仍然没有任何变化,程序在同一点停止,并出现相同的错误消息 . 我也尝试使用 mp_set_memory_functions() 并创建一个自定义 mallocWrapper() 并给它GMP,但是它没有't seem to work either. Of course I' 99%肯定,它是's because I'新的GMP和相对新的使用 malloc() 所以我的代码可能让你们大多数人撕裂你的头发现在出去,我为此道歉 .
所以基本上我的问题是:我应该如何使用 malloc() 为数字获得足够的内存?
在此先感谢您的帮助!
2 回答
这些线:
对我来说看起来很不对(你的整个源代码都很糟糕,你应该放弃它) . 看来你想分配101000000个不同的bignums,我不明白为什么你需要这么多 .
仔细阅读GMPlib的文档和Fibonnaci numbers的定义 . 你只需要一些
mpz_t
(很可能你需要不到六个mpz_t
变量),而不是数百万个 . 在编写程序之前考虑Fibonacci的数学定义 . 请注意,如果您知道Fib(10000)和Fib(10001),使用GMPlib计算Fib(10002)很容易,那么您不再需要Fib(10000),并且可以一旦打印出Fib(10002)计算 . 请注意,您可以使用mpz_set分配GMP大整数 .(你真的应该在考虑数学后从头开始重写你的程序;你可以转储你现有的代码)
不要忘记初始化每个变量,以适当地调用mpz_init .
编译所有警告和调试信息(
gcc -Wall -Wextra -g
) . Use the debugger (gdb
)和valgrind也许-fsanitize= debugging options据我所知,你的代码中甚至不需要单独显式调用
malloc
(当然,内部GMPlib正在使用malloc
) .(顺便说一句,作为一名学生,假设你的运动很容易,这是有帮助的)
如果GMP库无法处理它,请查看使用char *和算法来处理数字 . 您可以轻松地做任何GMP可以支持的事情 .