tags:

views:

55

answers:

3

Hello. I'm working with gnump and have a function that must return mpz_t. So I have to use raw pointers to return a value. I allocate space with new for pointer and send it as a parameter in my function.

I think it is better to use smart pointers. But I didn't work with them before. I read the manual but still can't understand how to use shared_ptr properly to return a variable from a function.

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;
}

I would be grateful for any example.

+1  A: 

if you wanted to return z without copying it, it would be


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

    return z;
}
DaVinci
+4  A: 

The use of shared pointers in this context does not help you. The type mpz_t itself is pointer-like. Such a pointer is initialised by calling any of the mpz_init_... functions. However, you need to call a mpz_clear to free the space allocated by the init function you've used.

Storing the pointer-like in a shared_ptr does not have the effect you want. It does keep track of the number of references to your mpz_t variable, and it does also delete mpz_t variable once there are no more references to it. However, that only frees the mpz_t variable itself, which is pointer-like. It does not call the mpz_clear function.

Smart pointers are extremely helpful, but they are meant to refer to class objects, not pointer-like variables. They take care of the destruction of the object they reference. Which makes sense if they reference a complex object, but not if they reference a pointer.

GNU MP offers a C++ class interface. (Look for mpz_class)

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

If you need to pass an mpz_t to other functions, you can obtain it from the shared pointer:

p->get_mpz_t()

where p is of type shared_ptr<mpz_class>.

svenor
+1  A: 

You can create a custom deleter that will be called by a smart-pointer, although it needs a pointer type. If you want to use mpz_t rather than a pointer and use mpz_clear on destruction, you can possibly write your some wrapper to do that, or even implement it yourself, although you can't use shared_ptr directly which expects a pointer.

Alternatively, and far preferable, you might actually consider using GNU's C++ interface which uses mpz_class rather than mpz_t and I imagine handles the cleanup for you.

CashCow