C++自定义String类中无法删除char[]成员变量问题
问题分析与解决:自定义String类delete[]崩溃的原因
核心崩溃原因
你程序崩溃的直接原因是尝试用delete[]释放栈上分配的内存。
在main函数里,temp是栈上的局部数组:
char temp[] = {'a','b','c','d'};
而你的构造函数直接把data指向了这个栈数组:
String::String(char str[], int _size) { data = str; // 直接指向外部栈内存,而非自己分配的堆内存 size = _size; }
delete[]只能用来释放通过new[]在堆上分配的内存,对栈内存执行delete[]属于未定义行为,必然导致程序崩溃。
正确的内存管理方案
自定义String类必须管理属于自己的堆内存,采用深拷贝而非浅拷贝。修改后的关键代码如下:
修正后的类实现
class String { public: String(); String(const char str[], int size); // 加const更合理,避免误修改原数组 ~String(); void clear(); private: char *data = nullptr; // 初始化指针为nullptr,避免野指针 int size = 0; }; String::String() = default; // 默认构造函数可以简化 String::String(const char str[], int _size) { size = _size; if (size > 0) { data = new char[size]; // 自己分配堆内存 // 拷贝数据 for (int i = 0; i < size; ++i) { data[i] = str[i]; } // 或者用memcpy更高效:memcpy(data, str, size * sizeof(char)); } } String::~String() { clear(); // 复用clear函数做内存释放 } void String::clear() { if (data != nullptr) { // 检查指针是否有效 delete[] data; data = nullptr; // 释放后置空,避免野指针和二次释放 } size = 0; }
对“尝试new后仍崩溃”的说明
你提到尝试用new char[4]分配内存后依旧崩溃,大概率是以下问题:
- 二次释放:比如你的析构函数也执行了
delete[] data,而clear里又执行一次,导致重复释放同一块内存。上面的代码通过在clear里把data置为nullptr,且delete[] nullptr是安全的,避免了这个问题。 - 指针未正确指向堆内存:可能你分配了堆内存,但没有把
data指向它,还是指向了栈数组。
关键注意事项
- 内存分配/释放必须匹配:
new[]对应delete[],栈内存绝对不能用delete释放。 - 自定义类管理内存时,指针初始化为
nullptr,释放后置空,避免野指针和二次释放。 - 涉及外部数组的构造函数,必须做深拷贝,不能直接复用外部指针,否则会失去对内存的控制权,还可能引发内存访问错误。
内容的提问来源于stack exchange,提问作者CuberBoy
相关产品推荐
相关产品推荐

