使用Malloc处理GMP中的大量数据 解决了的:

使用Malloc处理GMP中的大量数据 解决了的:,c,memory,malloc,dynamic-memory-allocation,gmp,C,Memory,Malloc,Dynamic Memory Allocation,Gmp,我觉得自己很愚蠢。GMP很好,这是我的疏忽。使用size\u t mpz\u sizeinbase(const mpz\u t op,int base)后,我意识到我用来复制结果的字符数组太小了。增加它的大小解决了这个问题。谢谢你的帮助 我的任务是编写一个C程序,计算从1024个元素到1048576个元素的斐波那契序列元素(从2的10次方到2的20次方,增加2次方)。为此,我使用GMP库来处理这些数字。问题是,大约2的17次方,这个数字太大了,连GMP都无法处理,这意味着我应该使用malloc

我觉得自己很愚蠢。GMP很好,这是我的疏忽。使用
size\u t mpz\u sizeinbase(const mpz\u t op,int base)
后,我意识到我用来复制结果的字符数组太小了。增加它的大小解决了这个问题。谢谢你的帮助


我的任务是编写一个C程序,计算从1024个元素到1048576个元素的斐波那契序列元素(从2的10次方到2的20次方,增加2次方)。为此,我使用GMP库来处理这些数字。问题是,大约2的17次方,这个数字太大了,连GMP都无法处理,这意味着我应该使用malloc()

这是我的main()(我修改了粘贴的代码,删除了不必要的部分,如写入文件和时间测量,它们将用于程序的另一部分):

intmain(){
int powersOfTwo[11];
char res[10000];
char*c;
c=分辨率;
对于(int i=0;i<11;i++){
powersOfTwo[i]=正常功率(2,i+10);
}
对于(int i=0;i<11;i++){
fibo(c,powersOfTwo[i]);
printf(“斐波那契的第%d个元素是%s\n”,powersOfTwo[i],res);
memset(res,0,sizeof res);
}
返回0;
} 
下面是一个简单的normalPower函数(为了清楚起见,它与问题无关):

intnormalpower(intn1,intn2){
如果(n2==0){
返回1;
}否则{
内部温度=n1;
对于(int i=1;i
现在的问题是,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); 
}
void fibo(字符*c,整数n){
mpz_t*fib1;
mpz_t*fib2;
温度;
fib1=(mpz_t*)malloc(101000000*sizeof(mpz_t));
fib2=(mpz_t*)malloc(101000000*sizeof(mpz_t));
temp=(mpz_t*)malloc(101000000*sizeof(mpz_t));
如果(NULL==fib1 | | NULL==fib2 | | NULL==temp){
printf(“错误:内存不足\n”);
}
mpz_init(*fib1);
mpz_init(*fib2);
mpz_初始(*温度);
mpz_set_str(*fib1,“0”,10);
mpz_set_str(*fib2,“1”,10);
int i;
如果(n==0){
char*d=mpz_get_str(NULL,10,*fib1);
strcpy(c,d);
}
如果(n==1){
char*d=mpz_get_str(NULL,10,*fib2);
strcpy(c,d);
}
如果(n>1){
对于(i=1;i
最初我只使用mpz_t-s,初始化它们,最后使用mpz_clear(),没有指针和malloc(),但这导致了分段错误(内核转储)在计算17(-ish)元素的幂2后出错。这是我在互联网上找到的一个解决方案,这几乎是我能分配的最大数量,仍然没有任何变化,程序在同一点停止,并显示相同的错误消息。我还尝试使用mp\u set\u memory\u functions()创建一个自定义mallocWrapper(),并赋予它GMP,但这似乎也不起作用。当然,我99%肯定,这是因为我是GMP新手,并且对使用malloc()相对较新,所以我的代码可能会让你们中的大多数人现在感到毛骨悚然,对此我深表歉意

因此,基本上我的问题是:我应该如何使用malloc()为数字获取足够的内存


提前谢谢你的帮助

如果GMP库无法处理,请考虑在算法中使用char*来处理数字。您可以轻松完成GMP支持的任何操作。

以下几行:

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));
在我看来,这是非常错误的(而且你的整个源代码闻起来非常糟糕,你应该放弃它)。看起来你想要分配101000000个不同的bignum,我不明白你为什么需要那么多

仔细阅读的文档和的定义。您只需要几个
mpz\u t
(很可能您需要的
mpz\u t
变量不到半打),而不是数百万个。在编写程序之前,考虑一下斐波那契的数学定义。请注意,如果您知道Fib(10000)和Fib(10001)使用GMPlib计算Fib(10002)很容易,那么您就不再需要Fib(10000),您可以在计算完Fib(10002)后立即打印它。请注意,您可以使用来分配大整数

(你真的应该在考虑了数学问题后从头开始重写你的程序;你可以转储你现有的代码)

不要忘记初始化每个变量,并适当地调用它们

使用所有警告和调试信息编译(
gcc-Wall-Wextra-g
使用调试器(
gdb
),也许

据我所知,您甚至不需要在代码中显式调用
malloc
(当然,GMPlib内部使用的是
malloc


(顺便说一句,作为一名学生,假设你的练习很容易完成是有帮助的)

Argh,代码没有意义……为什么不使用
pow
函数而不是
normalPower
函数呢?
pow
函数已优化。对于一个GMP bignum,不需要显式地
malloc
。GMP库处理其内部内存分配。你真的应该花几个小时阅读它的文档作为初学者,你真的应该使用C++,它隐藏了大部分的痛苦为你。code>#include
,然后像使用int一样使用类型
mpz_类
,只是它神奇地具有无限精度。会被视为作弊吗?我最初的代码只使用了mpz_t-s和mpz_clear()-ing,正如我所提到的。我知道我在代码中使用malloc的方式很糟糕,但我仍然需要一个w
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 *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));