2016-07-08 2 views
1

J'essaye d'implémenter une liste liée qui contient un tableau GMP rationnel mpq_t comme ses données, de plus je veux qu'elle garde la longueur à la fin de la liste courante actuelle lte et pour la commodité la longueur de le tableau n. Pour le tester, je génère arbitrairement des tableaux mpq_t et je l'envoie dans ma fonction GMPlist_push qui est destinée à créer un nouveau nœud qui contient la matrice.Liste liée avec des variables GMP

Le code ci-dessous fonctionne, cependant soit j'ai oublié quelque chose de trivial ou il y a un problème avec mon installation GMP. Quand je l'exécute, il est censé diffuser 5 nombres aléatoires et ensuite me dire dans quel nœud il est, mais sur mon MacBook il va 1, 4294967297, 4294967298, 4294967297 et puis il continue à osciller entre les deux, quand je lance le exactement le même code sur mon bureau Debian il fait le 1,2,3 désiré ...

Cela semble un comportement «imprévisible» qui sur la machine Linux semble fonctionner en ma faveur et il ne fonctionne pas sur mon Mac. Pouvez-vous voir quelque chose que j'ai oublié? Aussi pouvez-vous reproduire un comportement erroné?

Il est à noter que bien que l'exécutable s'exécute sans erreur, lldb se bloque avec des erreurs malloc obscures.

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 
#include <gmp.h> 
#include <assert.h> 

struct GMPlist { 
    mpq_t* data; 
    size_t n, lte; 
    struct GMPlist* next; 
}; 

typedef struct GMPlist GMPlist; 

mpq_t *randomVector(size_t n){ 
    mpq_t* retVal; 
    retVal = malloc(n*sizeof(*retVal)); 
    size_t i; 
    size_t den,num; 
    for (i = 0; i < n; i++){ 
     mpq_init(retVal[i]); 
     den = (size_t)rand(); 
     num = (size_t)rand(); 
     mpq_set_ui(retVal[i],den,num); 
     mpq_canonicalize(retVal[i]); 
    } 
    return retVal; 
} 


void GMPlist_push(GMPlist** elem, mpq_t* data){ 
    GMPlist* nextElem = malloc(sizeof(GMPlist*)); 

    nextElem->next = *elem; 
    nextElem->lte = (*elem)->lte + 1; 
    nextElem->n = (*elem)->n; 

    nextElem->data = data; 
    *elem = nextElem; 
} 

int main(int argc, char const *argv[]) 
{ 
    GMPlist* elem = malloc(sizeof(GMPlist)); 


    srand(time(NULL)); 

    elem->next = NULL; 
    elem->lte = 0; 
    elem->n = 5; 
    mpq_t* tester; 
    size_t i,j; 

    for (j = 0; j<10; j++){ 
     tester = randomVector(5); 

     GMPlist_push(&elem, tester); 

     for (i=0; i<5; i++){ 
      mpq_out_str(stdout,10,elem->data[i]); 
      fprintf(stdout, " "); 
     } 
     fprintf(stdout, ", %lu\n", elem->lte); 
    } 
return 0; 
} 

Merci, Rainer

Répondre

0

En GMPlist_push, vous n'êtes pas allouer la quantité de mémoire:

GMPlist* nextElem = malloc(sizeof(GMPlist*)); 

Vous voulez la taille d'un GMPlist, mais vous obtenez la taille d'un GMPlist *, ce qui est plus petit.

Pour ce faire, à la place:

GMPlist* nextElem = malloc(sizeof(GMPlist)); 

Si vous exécutez le code sous valgrind, il vous montrera où vous lisez/écriture en mémoire que vous n'êtes pas censé.

+0

Votre réponse résout le problème! Je vous remercie! Valgrind et GMP ne fonctionnent pas bien ensemble, c'est l'un des problèmes connus avec GMP. [Cliquez] (https://gmplib.org/manual/Debugging.html#Debugging) –