我在使用 boost::regex 时遇到了一个奇怪的行为。
以下函数调用自身一次(如果使用参数“true”调用)。
void regex_rek(bool recurse)
{
boost::smatch match;
if ( recurse )
{
std::string txt( "aaa" );
boost::regex rgx("aaa");
boost::regex_match(txt, match, rgx );
}
else
{
std::string txt("bbb");
boost::regex rgx("bbb");
boost::regex_match(txt, match, rgx );
}
std::cout <<"before: "<< std::string(match[0]) << std::endl;
if (recurse)
{
regex_rek(false);
}
std::cout <<"after: "<< std::string(match[0]) << std::endl;
}
这个的输出应该是
before: aaa
before: bbb
after: bbb
after: aaa
但它是(对我来说,在 ubuntu-64 位上运行,使用 boost-1.48):
before: aaa
before: bbb
after: bbb
after: bbb
在 win64、msvc11、boost-1.53 上我得到了其他东西:
before: aaa
before: bbb
after: bb
after: aa
不是开玩笑。这是我的错吗?我在某个地方犯了一个大错误吗?
我发现如果我使用 cmatch
版本,一切都很好。但这对我来说别无选择,因为我的字符串可能包含 0x0
。
最佳答案
smatch
不包含匹配数据的拷贝;相反,它包含指向它的指针。匹配的数据是变量 txt
,它在您调用 regex_match
后立即超出范围。此时,访问 match
是未定义的行为,任何事情都可能发生。
在match
之前声明txt
,并在if分支中赋值给它,它应该可以正常工作。
cmatch
版本可能有效,因为它包含指向字符串文字的指针,该文字永远不会超出范围。
关于c++ - 递归函数中的boost regex smatch表现得像一个静态变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17068690/