boost::match_results出现段错误,请求排查解决方法
Boost::match_results 段错误问题解决
问题场景
使用boost正则迭代器处理文本时触发段错误,错误发生在boost::match_results的operator[]函数中,相关代码及错误位置如下:
业务代码
boost::regex mulRegex(R"rgx(mul\(\d+,\d+\))rgx"); auto mulBegin = boost::sregex_iterator(inputData.begin(), inputData.end(), mulRegex); bool isMulValid = true; boost::regex doDontRegex(R"rgx((do(?!n't)|(?<!do )n't))rgx"); auto doDontBegin = boost::sregex_iterator(inputData.begin(), inputData.end(), doDontRegex); std::vector<std::string> mulMatches; auto dIt = doDontBegin; for (auto it = mulBegin; it != boost::sregex_iterator(); it++) { boost::smatch doDontMatch = *dIt; boost::smatch mulMatch = *it; if ((std::distance(dIt, it) < 0) && (doDontMatch.str() == "do")) { //segfault here isMulValid = true; dIt++; } else if ((std::distance(dIt, it) < 0) && (doDontMatch.str() == "don't")) { isMulValid = false; dIt++; } if (isMulValid) { mulMatches.push_back(mulMatch.str()); } }
错误发生位置(match_results.hpp)
const_reference operator[](int sub) const { if(m_is_singular && m_subs.empty()) //segfault here raise_logic_error(); sub += 2; if(sub < (int)m_subs.size() && (sub >= 0)) { return m_subs[sub]; } return m_null; }
错误原因分析
- 迭代器越界解引用:代码直接解引用
dIt但未检查其是否已到达结束迭代器(boost::sregex_iterator())。当所有do/don't匹配完成后,dIt变为无效状态,解引用会访问非法内存,触发段错误。 - 非法迭代器距离计算:
std::distance(dIt, it)属于未定义行为——dIt和it是对应不同正则表达式的独立迭代器,不属于同一迭代范围,无法通过distance判断位置关系。 - 位置判断逻辑错误:原代码试图用迭代器距离判断匹配顺序,这种方式完全不可靠,正确做法是直接比较匹配结果在原始文本中的起始位置。
修复方案
修复后的代码
boost::regex mulRegex(R"rgx(mul\(\d+,\d+\))rgx"); auto mulBegin = boost::sregex_iterator(inputData.begin(), inputData.end(), mulRegex); bool isMulValid = true; boost::regex doDontRegex(R"rgx((do(?!n't)|(?<!do )n't))rgx"); auto doDontBegin = boost::sregex_iterator(inputData.begin(), inputData.end(), doDontRegex); std::vector<std::string> mulMatches; auto dIt = doDontBegin; for (auto it = mulBegin; it != boost::sregex_iterator(); ++it) { const boost::smatch& mulMatch = *it; // 同步dIt到当前mul匹配之前的最后一个do/don't结果 while (dIt != boost::sregex_iterator() && (*dIt).position() <= mulMatch.position()) { const boost::smatch& doDontMatch = *dIt; if (doDontMatch.str() == "do") { isMulValid = true; } else if (doDontMatch.str() == "don't") { isMulValid = false; } ++dIt; } if (isMulValid) { mulMatches.push_back(mulMatch.str()); } }
关键修复点
- 迭代器有效性检查:每次使用
*dIt前先判断dIt != boost::sregex_iterator(),确保迭代器指向有效匹配结果。 - 基于位置的匹配同步:通过
position()方法获取匹配结果在原始文本中的起始位置,以此同步do/don't和mul的匹配顺序,替代错误的std::distance用法。 - 使用引用避免拷贝:用
const boost::smatch&替代值拷贝,既提升效率,也避免拷贝无效匹配结果导致的潜在问题。
内容的提问来源于stack exchange,提问作者venyanwarrior
相关产品推荐
相关产品推荐

