J'apprends actuellement libgmp et à cette fin j'écris un petit programme qui trouve les facteurs premiers. Mon programme appelle une fonction qui remplit un tableau avec une quantité variable d'entiers mpz_t, facteurs premiers d'un nombre donné, que j'ai besoin de retourner. Je prévois de mettre le dernier élément à NULL, donc je sais combien de mpz_t entiers la fonction trouvée.double erreur libre avec le pointeur vers le tableau de mpz_t
Mon problème est que j'obtiens des doubles erreurs libres avec mon tableau de pointeurs vers des entiers mpz_t. J'ai rédigé un exemple de code illustrant mon problème:
#include <stdlib.h>
#include <stdio.h>
#include <gmp.h>
int main(void)
{
mpz_t *p = malloc(5*sizeof(mpz_t*));
mpz_init_set_ui(p[0], 2UL);
mpz_init_set_ui(p[1], 5UL);
gmp_printf("%Zd %Zd\n", p[0], p[1]);
mpz_clear(p[0]);
mpz_clear(p[1]);
free(p);
return 0;
}
2 et 5 sont imprimés à stdout, si l'allocation semble bien. Mais je reçois la double sans erreur ci-dessous:
2 5
*** glibc detected *** ./lol: double free or corruption (out): 0x08e20020 ***
======= Backtrace: =========
/lib/libc.so.6(+0x6b6c1)[0xb77126c1]
/lib/libc.so.6(+0x6cf18)[0xb7713f18]
/lib/libc.so.6(cfree+0x6d)[0xb7716f8d]
/usr/lib/libgmp.so.3(__gmp_default_free+0x1d)[0xb77f53fd]
/usr/lib/libgmp.so.3(__gmpz_clear+0x2c)[0xb77ff08c]
./lol[0x80485e3]
/lib/libc.so.6(__libc_start_main+0xe6)[0xb76bdb86]
./lol[0x80484e1]
Je suis encore totalement habitué à obtenir des pointeurs, et gcc donne aucune erreur, mais je suis assez sûr que ce ne va pas et que je devrais faire quelque chose comme
mpz_init_set_ui(*p[0], 2UL);
au lieu de:
mpz_init_set_ui(p[0], 2UL);
Mais cela me donne une erreur du compilateur
test.c:8: error: incompatible type for argument 1 of ‘__gmpz_init_set_ui’
/usr/include/gmp.h:925: note: expected ‘mpz_ptr’ but argument is of type ‘__mpz_struct’
Quoi qu'il en soit, mes questions sont les suivantes:
- Je suis sûr que je devrais déréférencement le pointeur dans la mpz_init_set_ui() appel, pourquoi est-ce mal?
- Y a-t-il une meilleure façon de procéder? Dois-je utiliser une liste chaînée (je n'ai pas encore appris les listes chaînées, je pense qu'un tableau est le meilleur pour cela, mais si je suis vraiment en train de compliquer les choses, dites-le moi) 3.Fait-il mieux struct avec un pointeur vers mon tableau et une autre variable avec la quantité d'éléments dans mon tableau et retourner un pointeur à la place?
La plate-forme est Linux 32 bits juste au cas où cela est pertinent.
Voici le code que je viens de faire, que je veux modifier, je déclare le tableau de mpz_t sur la pile. Mais je veux faire main() une fonction:
#include <stdio.h>
#include <stdlib.h>
#include "prime.h"
#define MAXFACTORS 100
int main(void)
{
mpz_t numToFactor, factor;
mpz_t result;/* used to pass return values from getPrimeFactor() */
mpz_t primeFactors[MAXFACTORS];
mpz_init_set_str(numToFactor, "18 446 744 073 709 551 615 436 457 568", 10);
mpz_init(factor);
mpz_init(result);
int pFLen = 0;
mpz_init(primeFactors[pFLen]);
getPrimeFactor(numToFactor, result);
mpz_set(factor, result);
while(mpz_cmp_ui(factor, 0UL))
{
mpz_set(primeFactors[pFLen], factor);
pFLen++;
if(pFLen == MAXFACTORS)
{
puts("Ran out of space to store prime factors, quitting...");
}
mpz_init(primeFactors[pFLen]);
mpz_divexact(factor, numToFactor, factor);
mpz_set(numToFactor, factor);
getPrimeFactor(factor, result);
mpz_set(factor, result);
}
mpz_set(primeFactors[pFLen], numToFactor);
pFLen++;
int i;
for(i = 0; i < pFLen; i++)
{
gmp_printf("%Zd ", primeFactors[i]);
}
puts("");
mpz_clear(numToFactor);
mpz_clear(factor);
return 0;
}
Merci à l'avance, les gens
pourriez-vous poster le reste du code? –