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

自定义字符串类HomyshenTH_String的operator+=重载实现问题排查

自定义字符串类HomyshenTH_String的+=运算符空对象调用错误问题

我在实现自定义字符串类HomyshenTH_String时遇到问题:使用空初始化的字符串对象调用+=运算符时程序出错。我已经定义了默认构造函数=default,手动设置str=""和sz=0也无法解决问题。以下是类实现代码和测试代码:

类实现代码

HomyshenTH_String::HomyshenTH_String() = default;

HomyshenTH_String::HomyshenTH_String(const HomyshenTH_String& s)
{
    str = s.str;
    sz = s.sz;
}

HomyshenTH_String::HomyshenTH_String(const char* ch)
{
    int length = 0;
    while (ch[length] != '\0') length++;
    str = new char[length];
    for (int i = 0; i < length; i++) {
        str[i] = ch[i];
    }
    sz = length;
}

HomyshenTH_String& HomyshenTH_String::operator+=(const HomyshenTH_String& s)
{
    size_t old_size = this->sz;
    this->sz = old_size + s.sz;
    for (size_t i = 0; i < s.sz; i++) {
        this->str[i + old_size] = s[i];
    }
    return *this;
}

测试代码

HomyshenTH_String s("wordle");
const HomyshenTH_String s1("WORD");
s += s1; // 正常运行
s += "a"; // 正常运行
HomyshenTH_String MySubstr;
MySubstr += "a"; // 出错

问题原因

  1. 默认构造函数未初始化指针成员
    使用=default的默认构造函数不会初始化类的指针成员str,此时str是野指针。当空对象调用+=时,直接访问this->str[i + old_size]会触发未定义行为,导致程序崩溃。就算手动设置sz=0,str依然是野指针,没有指向合法内存,写入操作依然非法。

  2. operator+=未重新分配内存
    现有+=运算符只是修改了sz,就尝试在原内存后追加数据,但空对象根本没分配内存;就算是已初始化的对象,构造函数分配的内存仅够存原字符串,追加时会越界,同样属于未定义行为,只是没立刻崩溃而已。

  3. 拷贝构造函数的浅拷贝隐患
    当前拷贝构造函数直接复制指针,会导致多个对象共享同一块内存。当其中一个对象销毁释放内存后,其他对象的str就成了野指针,后续操作必然出错。

修复方案

  1. 正确实现默认构造函数
    手动初始化指针和大小,确保str合法:

    HomyshenTH_String::HomyshenTH_String() : str(nullptr), sz(0) {}
    
  2. 重写operator+=实现内存重分配
    追加前先分配足够新内存,复制原内容再追加新内容,最后释放旧内存:

    HomyshenTH_String& HomyshenTH_String::operator+=(const HomyshenTH_String& s)
    {
        size_t new_size = sz + s.sz;
        char* new_str = new char[new_size + 1]; // +1 存储字符串结束符'\0'
        
        // 复制原字符串
        for (size_t i = 0; i < sz; ++i) {
            new_str[i] = str[i];
        }
        // 追加新字符串
        for (size_t i = 0; i < s.sz; ++i) {
            new_str[sz + i] = s.str[i];
        }
        new_str[new_size] = '\0'; // 必须添加结束符
        
        // 替换内存
        delete[] str;
        str = new_str;
        sz = new_size;
        
        return *this;
    }
    
  3. 修复拷贝构造函数为深拷贝
    为新对象分配独立内存,避免共享内存问题:

    HomyshenTH_String::HomyshenTH_String(const HomyshenTH_String& s)
    {
        sz = s.sz;
        str = new char[sz + 1];
        for (size_t i = 0; i < sz; ++i) {
            str[i] = s.str[i];
        }
        str[sz] = '\0';
    }
    
  4. 添加析构函数释放内存
    必须清理分配的内存,防止内存泄漏:

    HomyshenTH_String::~HomyshenTH_String()
    {
        delete[] str;
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 18:15:15