Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 375
afalco Avatar asked May 11 '12 14:05

afalco


1 Answers

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.

like image 143
Matthieu M. Avatar answered Oct 12 '22 10:10

Matthieu M.