3

boost::regex を使用すると奇妙な動作に遭遇しました。

次の関数は、自分自身を 1 回呼び出します (引数 '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は未定義の動作であり、何が起こる可能性があります。

txtの前に宣言matchし、if ブランチ内で代入すると、正しく動作するはずです。

このcmatchバージョンは、スコープ外に出ることのない文字列リテラルへのポインターが含まれているため、おそらく機能します。

于 2013-06-12T15:21:22.410 に答える