3

我使用 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-64bit 上运行,使用 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.

4

1 回答 1

2

smatch不包含匹配的数据副本;相反,它包含指向它的指针。匹配的数据是变量txt,它在您调用后立即超出范围regex_match。在这一点上,访问match是未定义的行为,任何事情都可能发生。

声明txtbefore match,并在 if 分支中分配给它,它应该可以正常工作。

cmatch版本可能有效,因为它包含指向字符串文字的指针,该字符串永远不会超出范围。

于 2013-06-12T15:21:22.410 回答