Why do a C++ regular expression code that works with "cmatch" raises an exception with "smatch"?

c++, regex, visual-studio-2010

Solution

The issue is one of temporaries.

`smatch` will contain iterators into the string you are searching for.

`regex_search(string("xabcd"), mr, rx)` creates a temporary string that dies at the `;`.

Therefore by the time you use `mr` at the next line, it refers to invalidated memory. The `string` should live longer than `mr`.

Problem

I am new to C++ regular expressions and cannot make them work with strings instead of char*. The examples I have seen so far were always for c strings. My real program, which I will not even try to show here, uses sub matches but I could not make them work, so I tried to modify a very simple working example but it does not work either. I use Visual Studio 2010 Ultimate. The original - working - code: ``` const char *first = "abcd"; const char *last = first + strlen(first); std::cmatch mr; std::regex rx("abc"); std::regex_constants::match_flag_type fl = std::regex_constants::match_default; std::cout << "search(f, l, \"abc\") == " << std::boolalpha << regex_search(first, last, mr, rx) << std::endl; std::cout << " matched: \"" << mr.str() << "\"" << std::endl; std::cout << "search(\"xabcd\", \"abc\") == " << std::boolalpha << regex_search("xabcd", mr, rx) << std::endl; std::cout << " matched: \"" << mr.str() << "\"" << std::endl; ``` The modified code: ``` const string first = "abcd"; // char * => string std::smatch mr; // cmatch => smatch std::regex rx(string("abc")); std::regex_constants::match_flag_type fl = std::regex_constants::match_default; // this works: std::cout << "search(f, l, \"abc\") == " << std::boolalpha << regex_search(first, mr, rx) << std::endl; std::cout << " matched: \"" << mr.str() << "\"" << std::endl; // after the next line executes mr seems good to me: // mr[0] = {3, matched:true, first="abcd", second="d",...} std::cout << "search(\"xabcd\", \"abc\") == " << std::boolalpha << regex_search(string("xabcd"), mr, rx) << std::endl; // but the following line gives the error // "Debug assertion failed" // Expression: string iterators incompatible std::cout << " matched: \"" << mr.str() << "\"" << std::endl; ``` Strange that one part of the modified code works, while the next part causes an exception. I even tried to use mr[0].str() but I got the same error message. Could you help me to solve this problem?

Original source