Josh Brittain
Josh Brittain

Reputation: 2212

boost shared_ptr casting to void*

I'm using libev which requires casting my data to a void* to be in compliance with their predefined structs. I need to cast boost::shared_ptr to a void* and then cast the void* back to a boost::shared_ptr. Here is my code to do that

void foo(boost::shared_ptr<string>& a_string)
{
 void* data = (void*)a_string.get();
 boost::shared_ptr<string> myString((string*)data);
}

I'm pretty sure this works fine, however the way my code is setup I believe all shared_ptr references to my string are going out of scope as this casting method does not increase the use_count and thus shared_ptr is freeing the memory while I still need it.

Is there a way to manually increment/decrement the use_count? Ideally I would increment the use_count when I cast to a void*, pass my void* to another function, cast the void* back to a shared_ptr and decrement the use_count.

Or if anyone knows another solution to this problem I could use any help.

Upvotes: 5

Views: 2505

Answers (3)

Puppy
Puppy

Reputation: 146910

The only real way to do this to allocate a shared_ptr somewhere that will live for long enough, and then set the void* to point to that.

Upvotes: 4

David Miani
David Miani

Reputation: 14668

If you cast a void* back to a boost::shared_ptr, it will be a new shared pointer, not linked to any other shared pointers that also point to the memory pointed to by the `void* variable.

What I think you need to do is add enabled_shared_from_this support to the classes you are thinking of using with shared_ptrs with that code.

This allows you to get a shared_ptr that will share ownership with existing shared_ptrs through a member function (shared_from_this) on your class.

See the boost enabled_shared_from_this docs for more details.

Upvotes: 1

Preet Kukreti
Preet Kukreti

Reputation: 8607

Try a weak_ptr :

shared_ptr<int> p(new int(5));
weak_ptr<int> q(p);

Edit: Sorry I did not read the question properly; you could try to keep it in scope so it does not get cleaned up

Update: A weak pointer may actually work if you reference the variable after your call because then the compiler cant optimise the destruction of the a_string shared_ptr (hence prevent decr refcount to zero -> release) before you make use of the underlying pointer

so you could do this:

void foo(boost::shared_ptr<string>& a_string)
{
 void* data = (void*)a_string.get();
 boost::shared_ptr<string> myString((string*)data);
 weak_ptr<string> temp(a_string); // prevent destruction before above line
 // or reference a_string in any meaningless way that CANT be optimised out 
 // pre-emptively by the compiler
}

a_string might still need to referenced somewhere outside of foo depending on the context and what you are doing with the void pointer (and if it creates a new copy or operates on the void data)

Upvotes: 0

Related Questions