自定义String类构造函数触发FATAL ERROR: SIGABRT问题求助
问题分析与修复方案
核心错误:nullptr分支未正确初始化当前对象
当传入other == nullptr时,你写的String();只是创建了一个临时String对象,这个对象创建后立刻销毁,完全不会对当前正在构造的对象的slength和ifmt成员做任何初始化。此时当前对象的这两个成员是未定义的垃圾值:
ifmt是野指针,后续析构函数执行delete[] ifmt时,会触发非法内存访问,直接导致SIGABRT信号(也就是你看到的崩溃)。slength的垃圾值也可能引发后续逻辑的异常。
关于“负长度”的误解
建议里的“负长度”大概率是误判——你的计数逻辑中count初始为0,循环只在other[i] != '\0'时递增,不可能出现负数。这个建议对你的问题没有针对性,不用理会。
修复代码
方案1:使用构造函数委托(C++11及以上推荐)
利用C++11的委托构造,让带const char*参数的构造函数先调用默认构造函数完成初始化,再处理非nullptr的情况:
String::String(const char* other) : String() // 先委托默认构造函数初始化slength和ifmt { if (other != nullptr) // 只处理非空指针的情况 { int count = 0; while (other[count] != '\0') { ++count; } slength = count; delete[] ifmt; // 先释放默认构造分配的空数组 ifmt = new char[slength + 1]; for (int i = 0; i < slength; ++i) { ifmt[i] = other[i]; } ifmt[slength] = '\0'; } // nullptr情况已经由默认构造处理完毕 } String::String() { slength = 0; ifmt = new char[slength + 1]; ifmt[0] = '\0'; }
方案2:直接在nullptr分支手动初始化
如果你不能用C++11的委托构造,就在nullptr分支里直接初始化成员:
String::String(const char* other) { if (other == nullptr) { slength = 0; ifmt = new char[1]; ifmt[0] = '\0'; } else { int count = 0; while (other[count] != '\0') { ++count; } slength = count; ifmt = new char[slength + 1]; for (int i = 0; i < slength; ++i) { ifmt[i] = other[i]; } ifmt[slength] = '\0'; } } String::String() { slength = 0; ifmt = new char[slength + 1]; ifmt[0] = '\0'; }
额外优化建议
- 计算字符串长度可以直接用标准库的
strlen(需要包含<cstring>),避免自己写循环出错:int count = strlen(other); - 记得为类实现析构函数,释放
ifmt的内存:
String::~String() { delete[] ifmt; }
- 还要实现拷贝构造函数和拷贝赋值运算符(遵循三/五法则),避免浅拷贝导致的重复释放问题。
内容的提问来源于stack exchange,提问作者Rurutiaza K
相关产品推荐
相关产品推荐

