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

递归函数中用变量存s.length()可行,直接调用却报错的原因?

问题分析:C++中len与s.length()的条件判断差异

代码示例

// recursive function
int helper(string s, int i) {
    int num = 0;
    int len = s.length();
    cout << "i" << i << endl;
    if (i == len) {
        return 1;
    }
    if (s[i] == '0') {
        return 0;
    }
    for (int j = 1; j <= 2; j++) {

        if (len - i - j >= 0) {         // OPTION 1
        // if (s.length() - i - j >= 0) {  // OPTION 2

            string str = s.substr(i, j);
            int n = stoi(str);
            if (n < 27) {
                cout << "call" << i << j << endl;
                num = num + helper(s, i + j); // recursion
            }
        }
    }
    return num;
}

int numDecodings(string s) {
    if (s == "") {
        return 0;
    }
    return helper(s, 0);
}

问题描述

在上述C++代码中,len存储了s.length()的值,且s在所有递归调用中均为常量,s.length()的值始终保持一致。为何使用len的OPTION 1可以正常运行,而直接使用s.length()的OPTION 2会报错?

原因解析

核心问题是无符号整数溢出导致的条件判断失效:

  • s.length()返回的是size_t类型(无符号整数),而i、j是int类型(有符号整数)。当计算s.length() - i - j时,i和j会被隐式转换为size_t类型。如果i + j > s.length(),计算结果本应为负数,但无符号整数无法表示负数,会触发溢出回绕,结果变成一个极大的正数,导致>=0的条件永远为真。
  • 此时执行s.substr(i, j)会触发字符串越界访问,因为i + j超出了字符串的实际长度,触发未定义行为(比如程序崩溃、内存访问错误)。

而OPTION 1中的len是int类型(有符号整数),当len - i - j < 0时,条件判断为假,直接跳过后续的substr操作,自然不会触发越界问题。

举个具体例子:假设字符串长度为3,当i=2、j=2时:

  • OPTION1:3 - 2 - 2 = -1 >=0为假,跳过后续代码;
  • OPTION2:size_t(3) - 2 -2会被当作无符号计算,结果为SIZE_MAX(系统最大无符号整数),>=0为真,执行substr(2,2),但字符串从索引2开始仅剩余1个字符,直接触发越界报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 02:05:21