Boost::Tokenizer / "string iterators incompatible" error on Visual C++ 2010 Express - runs ok on gcc4.6.0

Hi, The following piece of code is giving me "string iterators incompatible" error: ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include <iostream> #include <string> #include <boost/tokenizer.hpp> class Base { public: typedef boost::char_separator<char> sep_type_t; typedef boost::tokenizer<sep_type_t> tokenizer_t; Base(std::string s) : sep_(";"), tok_(s,sep_), i_(tok_.begin()) { } std::string nextToken() { if (i_!=tok_.end()) return *i_++; else return ""; } protected: sep_type_t sep_; tokenizer_t tok_; tokenizer_t::iterator i_; }; class Sub : public Base { public: Sub(std::string s) : Base(s) { std::string t = nextToken(); std::string u = nextToken(); std::string v = nextToken(); } void doSomething() { int x = 0; x +=1; } }; int main (int argc, char **argv) { Sub x("ASIF;Sohail;Kaleem;Maryam;Irfan;Khurram"); x.doSomething(); return 0; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// This code is compiling and running fine on GCC 4.6.0 / Fedora 15 / 64-bit. I hope somebody here will help me out on this. Best regards, Asif

Hi Asif, On Mon, Aug 1, 2011 at 10:45 AM, asif saeed <asif.lse2@gmail.com> wrote:
Base(std::string s) : sep_(";"), tok_(s,sep_), i_(tok_.begin()) { }
These lines are your problem -- the tokenizer stores the iterators from the string 's', but once the constructor is exited (prior to the body of the derived class being called) the argument 's' is destroyed -- invalidating the iterators stored by the tokenizer data member. Try the following change to Base: class Base { public: typedef boost::char_separator<char> sep_type_t; typedef boost::tokenizer<sep_type_t> tokenizer_t; Base(std::string s) : s_(s), sep_(";"), tok_(s_,sep_), i_(tok_.begin()) {} std::string nextToken() { if (i_!=tok_.end()) return *i_++; else return ""; } protected: std::string s_; sep_type_t sep_; tokenizer_t tok_; tokenizer_t::iterator i_; }; HTH, Nate

Hi Nathan, On Mon, Aug 1, 2011 at 11:26 PM, Nathan Crookston < nathan.crookston@gmail.com> wrote:
On Mon, Aug 1, 2011 at 10:45 AM, asif saeed <asif.lse2@gmail.com> wrote:
Base(std::string s) : sep_(";"), tok_(s,sep_), i_(tok_.begin()) { }
These lines are your problem -- the tokenizer stores the iterators
It causes problem on Visual C++ 2010 Express at run-time. However, it runs fine on GCC 4.6.0 / Fedora-15-64-bit. Sincerely, Asif

I still don't understand why it works on GCC 4.6.0 if storing string is necessary. Sincerely, Asif On Tue, Aug 2, 2011 at 9:24 AM, asif saeed <asif.lse2@gmail.com> wrote:
Hi Nathan,
On Mon, Aug 1, 2011 at 11:26 PM, Nathan Crookston < nathan.crookston@gmail.com> wrote:
On Mon, Aug 1, 2011 at 10:45 AM, asif saeed <asif.lse2@gmail.com> wrote:
Base(std::string s) : sep_(";"), tok_(s,sep_), i_(tok_.begin()) { }
These lines are your problem -- the tokenizer stores the iterators
It causes problem on Visual C++ 2010 Express at run-time. However, it runs fine on GCC 4.6.0 / Fedora-15-64-bit.

On Aug 2, 2011, at 2:31 AM, asif saeed <asif.lse2@gmail.com> wrote:
I still don't understand why it works on GCC 4.6.0 if storing string is necessary. Sincerely, Asif
Holding pointers or iterators on an object which has just been destroyed may occasionally work by accident if the memory hasn't been overwritten by the next thing.
participants (3)
-
asif saeed
-
Gordon Woodhull
-
Nathan Crookston