Boost sub_match引发std :: length_error异常

时间:2018-01-16 22:46:52

标签: c++ regex exception boost

我正在使用Boost Regex。我有以下代码(简化):

bool search_for_match(const string& data)
{
  boost::smatch results;
  if(boost::regex_search(data, results, my_regex))
  {
    if(results["REVISION"].matched)
    {
      std::string the_submatch = results["REVISION"].str();
      std::cout << the_submatch << std::endl;
    }
    return true;
  }
  return false;
}

my_regex是一个成功编译的正则表达式。我将the_submatch分配给results["SUBMATCH_TWO"].str()的行会引发std::length_error类型的异常,而what()会打印出basic_string::_S_create

阅读Boost sub_match上的文档,它指出如果matched为真,则将设置迭代器。为什么会爆炸? data字符串不会超出范围,但它肯定似乎是迭代器未定义或数据字符串已超出范围,这会使迭代器变坏。该文档还指出,如果matched为false,则只返回一个空字符串。所以,我知道匹配必须是真的,但迭代器都是乱码或其他东西。

这是正则表达式:

(?<FLIGHT_ID>[[:alnum:]]+)
\t[ ]{1,2}
(?<BEACON_CODE>[[:alnum:]]+)
\t[ ]{1,2}
((?=[A-Z]{2,5}[ ])(?<DEPARTURE_POINT>[A-Z]{2,5})[ ](?<DESTINATION_POINT>[A-Z]{2,5})|(?<DEPARTURE_POINT>[^\t ]{1,13}))
\t?[ ]{1,2}                                                                       
(?<ROUTE1>[[:print:]]+)
(?: \t[ ]+ (?<EDCT>[[:alnum:]]+) )?
\r\n
(?<REVISION>\d+)?
(?: \s+ (?<STRIP_ORIGINATOR>[[:alnum:]]+) )?
\r\n
(?<AIRCRAFT_TYPE>[[:alnum:]/ ]+)
\t[ ]{1,2}
P(?<DEPARTURE_TIME>\d+)
(?: [ ][ ]\t[ ]{1,2} )?
(?: (?<ROUTE2>[[:print:]]+) )?
(?: \t[ ][ ] )?
(?: (?<EDCT_TIME>\d+) )?
\r\n
\n
(?<COMPUTER_ID>[[:alnum:]]+)
\t[ ]{1,2}
(?<ALTITUDE>VFR/\d+|\d+)
(?: [\t ]*  (?<ROUTE3>[[:print:]]+) )?
\r\n?   

如您所见,REVISION命名子组是可选的。这就是我检查matched为真的原因。我像这样编译my_regex

boost::regex my_regex;
void compile_pattern(const string& pattern)
{
  try
  {
    boost::regex compiled_expression(pattern, boost::regex::mod_x);
    my_regex = compiled_expression;
  }
  catch(boost::regex_error& e)
  {
    std::cout << e.what() << std::endl;
  }
}

我读入包含该正则表达式的整个文件并将其存储到字符串中并将其传递给compile_patterns()函数。这似乎工作得很好,因为我没有看到抛出异常所以它似乎是一个有效的正则表达式给我。

1 个答案:

答案 0 :(得分:1)

导致此错误的常见罪魁祸首是从nullptr字符*构建std::string const时。

在您的情况下,这是不可能的,因为所有迭代器范围都表示为源字符串中的迭代器。那么,当问题超出所显示的代码时,似乎最合乎逻辑的解释是什么。

例如,您可以将data的陈旧引用作为std::string参数传递。这会调用this,这可以通过多种方式表现出来。

当解释用于保存{{1}}实例作为此类对象的内存,当该对象不再存在(它已被破坏,或者内存可能已经存在)时,这不是一个不太可能的场景被重新利用)导致一个解除引用空指针的迭代器。