c++ - 'vector iterators incompatible' -


this question has been asked number of times on so, answers not apply situation, afaict. following piece of code triggering error upon hitting i != std::end(observers_);.

void visualgeometry::signalpoppointflags(const point_2r& p,                                          const uint32_t msec_delay) const {     for(auto = std::begin(observers_); != std::end(observers_); ++i)         (*i)->slotpoppointflags(p, msec_delay); } 

looking <vector>, following triggers error:

void _compat(const _myiter& _right) const {   // test compatible iterator pair     if (this->_getcont() == 0         || this->_getcont() != _right._getcont())         {   // report error             _debug_error("vector iterators incompatible");             _scl_secure_invalid_argument;         } } 

since not comparing iterators different containers, seems first check this->_getcont() == 0 might problem, i'm not sure how tell.

the same problem occurs if swap out begin(vec)/end(vec) vec.begin()/vec.end().

i'm little lost how can happen. advice on how move forward debugging this?

the visualgeometry class designed forward signals receives onward whichever objects watching it. here relevant code snippets:

class visualgeometry : public igeometryobserver, public iobservablegeometry { public:     void slotpushsegmentflags(const segment_2r& s, const uint32_t flags,                               const uint32_t msec_delay = 0) override;     void slotpopsegmentflags(const segment_2r& s,                              const uint32_t msec_delay = 0) override;     void signalpushsegmentflags(const segment_2r& s, const uint32_t flags,                                 const uint32_t msec_delay = 0) const override;     void signalpopsegmentflags(const segment_2r& s,                                const uint32_t msec_delay = 0) const override;     /* snip */     private:     std::vector<igeometryobserver*> observers_; };  void visualgeometry::slotpushsegmentflags(const segment_2r& s,                                           const uint32_t flags,                                           const uint32_t msec_delay) {     signalpushsegmentflags(s, flags, msec_delay); }  void visualgeometry::slotpoppointflags(const point_2r& p,                                        const uint32_t msec_delay) {     signalpoppointflags(p, msec_delay); }  /* etc... */ 

the first thing check see if modifying vector iterating on iterate on it.

see if eliminates problem:

void visualgeometry::signalpoppointflags(const point_2r& p,                                          const uint32_t msec_delay) const {   auto obs = observers_;   for(auto = std::begin(obs); != std::end(obs); ++i)     (*i)->slotpoppointflags(p, msec_delay); } 

dealing kind of problem tricky, , sign have design problem.

in general, when calling sequence of callbacks, if callback has way reach sequence iterating on , change or members, need add in lifetime management code, , determine means callback sent when 1 being sent, , means if callbacks installed or uninstalled while callbacks being called.

a simple rule "you don't callbacks if installed while callbacks being installed", if uninstall callback, not called.

to produce effect, callbacks tend containers of weak_ptrs std::functions. when install callback, pass in std::function, copy shared_ptr. spawn weak_ptr off that, , store in callback container.

i return shared_ptr code installing callback. shared_ptr lifetime token: long (or copies of it) valid, continue make callbacks on it.

in broadcast function, first sweep container obsolete weak_ptrs, copy container local std::vector<std::weak_ptr<std::function<void(message)>>>.

i iterate on container, doing .lock() std::shared_ptr<std::function<void(message)>>, if valid calling it.

if broadcast triggered when i'm broadcasting, happens. (if happens often, i'll blow stack, problem). if adds callback, i'm fine. if removes callback, i'm fine.

if things multi-threaded, not locked when iterating on local std::vector, locked while clearing weak_ptrs aren't valid, , when cloning sequence of weak_ptrs, or when adding/removing callbacks vector<weak_ptr<function<...>>>.


Comments

Popular posts from this blog

Detect support for Shoutcast ICY MP3 without navigator.userAgent in Firefox? -

web - SVG not rendering properly in Firefox -

java - JavaFX 2 slider labelFormatter not being used -