自定义字符串类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"; // 出错
问题原因
默认构造函数未初始化指针成员
使用=default的默认构造函数不会初始化类的指针成员str,此时str是野指针。当空对象调用+=时,直接访问this->str[i + old_size]会触发未定义行为,导致程序崩溃。就算手动设置sz=0,str依然是野指针,没有指向合法内存,写入操作依然非法。operator+=未重新分配内存
现有+=运算符只是修改了sz,就尝试在原内存后追加数据,但空对象根本没分配内存;就算是已初始化的对象,构造函数分配的内存仅够存原字符串,追加时会越界,同样属于未定义行为,只是没立刻崩溃而已。拷贝构造函数的浅拷贝隐患
当前拷贝构造函数直接复制指针,会导致多个对象共享同一块内存。当其中一个对象销毁释放内存后,其他对象的str就成了野指针,后续操作必然出错。
修复方案
正确实现默认构造函数
手动初始化指针和大小,确保str合法:HomyshenTH_String::HomyshenTH_String() : str(nullptr), sz(0) {}重写
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; }修复拷贝构造函数为深拷贝
为新对象分配独立内存,避免共享内存问题: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'; }添加析构函数释放内存
必须清理分配的内存,防止内存泄漏:HomyshenTH_String::~HomyshenTH_String() { delete[] str; }
内容的提问来源于stack exchange,提问作者lilof
相关产品推荐
相关产品推荐

