
I've run into a problem where a weak_ptr<> is segfaulting when I try to do a lock() call on it. It doesn't happen all the time, and I'm at a loss to see what's causing the problem. I have an implementation of the Observer pattern in my code using shared_ptr/weak_ptr: class Observer { public: virtual void update(shared_ptr<Observed> d) = 0; ... } class Observed : public enable_shared_from_this<Observed> { vector<weak_ptr<Observer> > _observers; public: void register(shared_ptr<Observer> o) { _observers.push_back(weak_ptr<Observer>(o)); } void notifyObservers() { vector<weak_ptr<Observer> >::iterator i; for (i = _observers.begin(); i != _observers.end(); observer++) { shared_ptr<Observer> o = i->lock(); if (o) o->update(shared_from_this()); } } ... } I'm trying to write a wxWidget that participates in the above Observer scheme, but quickly ran into a problem: wxWidgets passes around raw pointers and handles its own garbage-collection. If I created a shared_ptr<MyWidget>, wx would feel perfectly free to delete the object out from under the shared_ptr<>, which would be bad. My solution was: template <typename T> class wxObserver : public Observer { private: T* p; wxObserver(); public: wxObserver(T* p) : p(p); void update(shared_ptr<Observed> o) { if (p) p->update(o); } } class MyWidget : public wxWidget { private: shared_ptr<wxObserver<MyWidget> > observer; public: MyWidget(...) : wxWidget(...), observer(this) { ... observed->register(observer); ... } ... } The idea is that when a MyWidget is created, it creates a shared pointer to a wxObserver and can register that wxObserver with observed objects without a problem. When wxWidgets chooses to delete the MyWidget, the shared pointer the MyWidget goes away, the wxObserver is deleted, and the weak pointers held by the observed objects expire. The implementation of Observed::notifyObservers() checks to make sure that the observers still exist before update()ing them, and only the live observers are updated. The problem is that sometimes, after wxWidgets destroys a MyWidget, calls to Observed::notifyObservers() crashes with a segfault within the call to i->lock(). I can't see what's causing this. Worse, while it crashes consistantly and repeatedly at the same line, it doesn't appear to always crash after the same amount of work. Putting various {cerr << "got here";}-type lines within the code above doesn't always yield exactly the same results from run to run, even without recompiling. My thoughts are now that it might be a threading issue. Is there any good solutions to this problem? thanks, Buddha