-
boost::shared_ptr
Ok, first I'll say what I want to do, then I'll explain why. I have a boost::shared_ptr<T>, and I want to tell the shared_ptr that, thank you very much, but please don't manage my pointer anymore, I'll go ahead and manage it.
The reason is this:
I have a stl container that has shared_ptr<T> in it. Items are removed on a time basis, at which point for each T* I create a thread with CreateThread(...) and pass the T* to it. Then it does some processing with that data. So I just added the shared_ptr to my implementation, and obviously I can't give shared_ptr<T> to CreateThread, so instead I call shared_ptr's .get function to get the raw pointer value. Then I pass the real pointer to CreateThread. When the handler function recieives the pointer, it puts it back into a shared_ptr and things continue. Well, not exactly. The problem is, since I removed my shared_ptr<T> from the container, the shared_ptr in the main thread is the only reference to the pointer. And when that shared_ptr goes out of scope, the memory that T points to gets deleted. And then the thread starts up, and I have a dangling pointer. BAM!
I just realized that I can't do what I want (tell shared_ptr not to manage the pointer anymore), because if the reference count happens to be greater than 1, i.e. other shared_ptr are pointing at the same memory, then what the hell are they supposed to do?!
I considered adding the shared_ptr to a second list<>, sort of a ready-to-be-processed-list, and then I pass the real pointer via CreateThread, and scan the ready list<> once the thread starts up and remove it. So basically I create a holding area for it. But that seems like a lot of work, considering that before I used shared_ptr it wasn't required...
So how do I solve this particular problem? Maybe it's just late. Maybe I should just look at it tomorrow morning. But does anyone have any ideas?
-
Use Boost.Thread to create the thread, and use Boost.Bind to bind the shared_ptr into the function object that's the thread startup function.
If that's too much work for you, do this:
Code:
typedef boost::shared_ptr<whatever> whatptr;
std::vector< whatptr > pointers;
for(auto it = pointers.begin(); it != pointers.end(); ++it) {
whatptr *pptr = new whatptr(*it);
__beginthreadex(threadfunc, ..., pptr);
}
unsigned int threadfunc(void *pv)
{
whatptr *paramptr = reinterpret_cast<whatptr *>(pv);
whatptr local(*paramptr);
delete paramptr;
}
-
CornedBee:
Eventually I may use the Boost.Threads approach that you mention. Certainly that's the "best" way of doing it. For now, I did something similar to your approach. Since the boost::shared_ptr was only pointing to a structure that was holding two other shared_ptrs, I just allocated a new struct, passed it to the thread, and the first thing the thread does it put the raw pointer back into a shared_ptr.
Thanks for the ideas and help.