C++自定义字符串类报double free detected in tcache 2错误如何解决
错误原因分析
- 拼接构造函数使用值传递参数触发浅拷贝:你的
Dstring(Dstring val1, Dstring val2)参数是值传递,调用时会生成str1、str2的临时拷贝对象,由于你没有实现自定义拷贝构造函数,编译器生成的默认拷贝构造是浅拷贝,仅复制value指针本身而非指向的内存内容。临时对象在构造函数执行结束后析构,会直接释放str1、str2原本指向的内存,等到main函数结束str1、str2析构时就会触发重复释放的错误。 - 字符串内存分配长度缺失终止符空间:C风格字符串以
\0作为结束标记,strlen返回的长度不包含该终止符,你所有new char分配内存时都少分配了1字节的终止符空间,strcpy、strcat操作会发生内存越界,属于未定义行为。 - 拼接构造函数未初始化目标内存直接调用
strcat:strcat要求目标指针指向的是合法的以\0结尾的字符串,你新分配的value内存是未初始化的,直接调用strcat会从随机内存位置开始拼接,结果异常。 - 动态内存释放方式不匹配:你用
new[]分配数组内存,却用delete而非delete[]释放,不符合C++动态内存管理规范,会引发未定义行为。 - 构造函数参数类型不规范:接收字符串字面值的构造函数参数应为
const char*,你强制将字面值转为char*属于不安全的类型转换。
修正后的完整代码
#include <iostream> #include <cstring> class Dstring{ private: char* value; public: // 接收C风格字符串的构造函数 Dstring(const char* val){ // 多分配1字节存储'\0' value = new char[strlen(val) + 1]; strcpy(value, val); } // 拼接构造函数,参数用常量引用避免值拷贝 Dstring(const Dstring& val1, const Dstring& val2){ int len1 = strlen(val1.value); int len2 = strlen(val2.value); // 多分配1字节存储'\0' value = new char[len1 + len2 + 1]; // 先复制第一个字符串初始化目标内存 strcpy(value, val1.value); // 再拼接第二个字符串 strcat(value, val2.value); } void show(){ std::cout << value << std::endl; } ~Dstring(){ std::cout << "Delete " << value << std::endl; // 数组内存用delete[]释放 delete[] value; } }; int main(){ Dstring str1("Hello "); Dstring str2(" World!"); Dstring str3(str1, str2); str3.show(); return 0; }
运行输出
Hello World! Delete Hello World! Delete World! Delete Hello
内容的提问来源于stack exchange,提问作者Anish Sapkota
相关产品推荐
相关产品推荐

