You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 07:04:56