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

自定义C++ String类substring函数字符数组初始化异常排查

问题分析与解决

嘿,这个问题我太熟悉啦!你遇到的乱码问题根源在于C风格字符数组必须以空终止符'\0'结尾,而你的代码里漏掉了这关键一步。

为什么会出现垃圾字符?

你当前的代码中:

char* r = new char[rlength];
for (int i = 0; i < rlength; i++) {
    r[i] = chars[i + startIndex];
}
string s2(r);
  • 你只分配了rlength大小的内存来存储子串的字符,但没有预留额外空间存放'\0'
  • 当用这个字符数组构造string对象时,它会从r的起始位置开始读取,直到找到一个'\0'才停止
  • 因为你没手动添加'\0',程序就会读取数组后面的随机内存数据,这就是你看到的"a�;�"这类垃圾字符的来源

修复方案

有两种简洁的修复方式,推荐第二种更安全的写法:

方式1:手动添加空终止符(修复原有逻辑)

修改数组分配和添加终止符:

string string::substring(unsigned int startIndex, unsigned int endIndex) const {
    if (startIndex >= endIndex) {
        return string();
    }
    if (endIndex > length) endIndex = length;
    int rlength = endIndex - startIndex;
    // 多分配1个字节存'\0'
    char* r = new char[rlength + 1];
    for (int i = 0; i < rlength; i++) {
        r[i] = chars[i + startIndex];
    }
    // 添加空终止符
    r[rlength] = '\0';
    string s2(r);
    // 记得释放内存,避免泄漏!
    delete[] r;
    return s2;
}

这里一定要记得delete[] r,不然会造成内存泄漏。

方式2:直接利用string的范围构造(更安全,无需手动管理内存)

如果你的自定义string类支持接受字符指针+长度的构造函数(类似标准std::string的string(const char* s, size_t n)),可以直接简化代码:

string string::substring(unsigned int startIndex, unsigned int endIndex) const {
    if (startIndex >= endIndex) {
        return string();
    }
    if (endIndex > length) endIndex = length;
    int rlength = endIndex - startIndex;
    // 直接从chars的起始偏移位置,取rlength个字符构造string
    return string(chars + startIndex, rlength);
}

这种写法完全避免了手动内存管理,也不需要依赖空终止符,更不容易出错。

验证修复效果

修复后,你的测试用例都会得到预期结果:

  • "This is a test".substring(9, 10) 会正确返回 "a",不再带有垃圾字符

额外提醒

如果你的自定义string类还没有实现带长度的构造函数,建议补上它——这会让很多字符串操作更安全,避免因为空终止符问题踩坑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:29:07