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

LeetCode findAnagrams提交报unsigned offset溢出错误排查求助

问题根源分析
  • 核心问题是无符号整数隐式转换导致的字符串下标越界:std::string::size()返回的是无符号类型size_t,当你用int类型的1+i和它做减法运算时,int会被隐式转换为无符号类型,运算结果也会是无符号类型。
  • 当1+i < p.size()时,1+i - p.size()的数学结果为负数,转换为无符号类型后会变成极大的正整数,此时你写的1+i - p.size() >= 0判断永远为真,程序会用这个非法的超大下标去访问s字符串,触发内存越界,和你看到的报错完全吻合。
  • 本地运行正常是因为默认编译选项没有开启UndefinedBehaviorSanitizer(UBSan)检查,越界访问的内存刚好没有触发段错误,属于未定义行为的随机表现,不代表代码本身没有问题。
复现方法
  • 构造最简单的触发用例:s = "a", p = "ab",此时p长度大于s长度,运行代码必然触发越界;所有s长度小于p长度的用例都可以稳定复现该问题。
  • 本地复现需要在编译时加上UBSan检查参数:g++ -fsanitize=undefined -o test test.cpp,运行编译后的程序就会弹出和LeetCode完全一致的报错。
修复方案

提前把p的长度转换为有符号int类型存储,避免隐式无符号转换即可:

bool find_match(const std::map<char, std::pair<int, int>> &m){
  for(const auto& [k, v] : m){
    if(v.first != v.second) return false;
  }
  return true;
}

std::vector<int> findAnagrams(std::string s, std::string p){
  std::vector<int> result;
  int p_len = static_cast<int>(p.size());
  // 提前加边界判断,s比p短直接返回空
  if (static_cast<int>(s.size()) < p_len) return result;
  std::map<char, std::pair<int, int>> search;
  for(const char& c : p){
    search[c].first++;
    search[c].second = 0;
  }

  for(int i = 0; i < s.size(); i++){
    if(p.find(s[i]) != p.npos)
      search[s[i]].second++;
    
    if(find_match(search))
      result.push_back(1 + i - p_len);

    int left = 1 + i - p_len;
    if(left >= 0 && p.find(s[left]) != p.npos)
      search[s[left]].second--;
  }

  return result;
}

内容的提问来源于stack exchange,提问作者ianwt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 00:24:03