Thread: boost::shared_ptr

  1. #1
    Registered User
    Join Date
    Aug 2002
    Location
    Hermosa Beach, CA
    Posts
    446

    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?
    The crows maintain that a single crow could destroy the heavens. Doubtless this is so. But it proves nothing against the heavens, for the heavens signify simply: the impossibility of crows.

  2. #2
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    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;
    }
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  3. #3
    Registered User
    Join Date
    Aug 2002
    Location
    Hermosa Beach, CA
    Posts
    446
    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.
    The crows maintain that a single crow could destroy the heavens. Doubtless this is so. But it proves nothing against the heavens, for the heavens signify simply: the impossibility of crows.

Popular pages Recent additions subscribe to a feed