2010-10-25 5 views
0

Je travaille avec gnump et avoir une fonction qui doit retourner mpz_t. Je dois donc utiliser des pointeurs bruts pour renvoyer une valeur. J'alloue l'espace avec new pour le pointeur et l'envoie en tant que paramètre dans ma fonction.GMP et pointeurs intelligents

Je pense qu'il est préférable d'utiliser des pointeurs intelligents. Mais je n'ai pas travaillé avec eux avant. J'ai lu le manuel, mais je ne comprends toujours pas comment utiliser correctement shared_ptr pour renvoyer une variable d'une fonction.

shared_ptr<mpz_t> func() 
{ 
    mpz_t z; 
    mpz_init_set_str(z, "23423423423", 10); 

    shared_ptr<mpz_t> p /* Shall I allocate space with "new" or smth else?.. */ 

    return p; 
} 

Je serais reconnaissant pour tout exemple.

Répondre

5

L'utilisation de pointeurs partagés dans ce contexte ne vous aide pas. Le type mpz_t lui-même est un pointeur. Un tel pointeur est initialisé en appelant l'une des fonctions mpz_init _.... Cependant, vous devez appeler un mpz_clear pour libérer l'espace alloué par la fonction init que vous avez utilisée.

Le stockage du pointeur dans un shared_ptr n'a pas l'effet souhaité. Il garde une trace du nombre de références à votre variable mpz_t, et il supprime également la variable mpz_t dès qu'il n'y a plus de références. Cependant, cela ne libère que la variable mpz_t elle-même, qui ressemble à un pointeur. Il n'appelle pas la fonction mpz_clear.

Les pointeurs intelligents sont extrêmement utiles, mais ils se réfèrent à des objets de classe, et non à des pointeurs. Ils prennent soin de la destruction de l'objet qu'ils référencent. Ce qui est logique s'ils font référence à un objet complexe, mais pas s'ils font référence à un pointeur. GNU MP propose une interface de classe C++. (Cherchez mpz_class)

shared_ptr<mpz_class> func() 
{ 
    shared_ptr<mpz_class> z(new mpz_class("23423423423", 10)); 
    return z; 
} 

Si vous devez passer un mpz_t à d'autres fonctions, vous pouvez l'obtenir à partir du pointeur partagé:

p->get_mpz_t() 

où p est de type shared_ptr <mpz_class>.

1

si vous vouliez revenir z sans le copier, il serait


shared_ptr func() 
{ 
    shared_ptr z(new mpz_t()); 
    mpz_init_set_str(*z, "23423423423", 10); 

    return z; 
}
1

Vous pouvez créer un suppresseur personnalisé qui sera appelé par un pointeur intelligent, bien qu'il nécessite un type de pointeur. Si vous voulez utiliser mpz_t plutôt qu'un pointeur et utiliser mpz_clear lors de la destruction, vous pouvez éventuellement écrire votre wrapper pour le faire, ou même l'implémenter vous-même, bien que vous ne puissiez pas utiliser shared_ptr directement qui attend un pointeur.

Alternativement, et de loin préférable, vous pourriez réellement envisager d'utiliser l'interface C++ de GNU qui utilise mpz_class plutôt que mpz_t et j'imagine gérer le nettoyage pour vous.