C++动态内存分配与赋值运算符重载程序排障求助
嘿,我仔细看了你这段C++代码,能看出你在练习动态内存分配和运算符重载的知识,不过有几个关键问题会导致程序出错,我帮你梳理并修正了:
你的代码存在的核心问题
- 默认构造函数未初始化指针:你的默认构造函数
myClass () {}里没有给ptr赋值,这会让ptr变成野指针,后续调用析构函数或者其他操作时大概率会触发崩溃。 - 普通构造函数内存分配不足:
ptr = new char[strlen(str)];里strlen(str)只计算字符串的有效字符数,不包含末尾的'\0',但strcpy会把终止符也拷贝过去,这就会导致内存越界,引发未定义行为。 - 赋值运算符重载缺失/未完成:你代码里只写了
myClass& o...,完整的赋值运算符重载是必须的——默认的赋值运算符会做浅拷贝,导致多个对象指向同一块内存,析构时重复释放内存触发崩溃。 - 缺少析构函数:没有写析构函数来释放
ptr指向的动态内存,会造成内存泄漏。
修正后的完整代码
#include <iostream> #include <cstring> using namespace std; class myClass{ private: char *ptr; public: // 默认构造函数:初始化ptr为nullptr,避免野指针 myClass () : ptr(nullptr) {} // 普通构造函数:分配内存时+1,容纳字符串终止符'\0' myClass (char *str) { if (str == nullptr) { ptr = nullptr; return; } ptr = new char[strlen(str) + 1]; strcpy(ptr, str); } // 拷贝构造函数:你原本的实现是对的,这里补充了空指针判断增强健壮性 myClass (const myClass &k) { if (k.ptr == nullptr) { ptr = nullptr; return; } ptr= new char [strlen(k.ptr)+1]; strcpy(ptr, k.ptr); } // 赋值运算符重载:实现深拷贝,处理自赋值和空指针情况 myClass& operator=(const myClass &k) { // 自赋值检查:避免自己给自己赋值时提前释放内存 if (this == &k) { return *this; } // 先释放当前对象已有的内存 delete[] ptr; // 拷贝新对象的内容 if (k.ptr == nullptr) { ptr = nullptr; return *this; } ptr = new char[strlen(k.ptr) + 1]; strcpy(ptr, k.ptr); return *this; } // 析构函数:释放动态分配的内存,避免泄漏 ~myClass() { delete[] ptr; } // 可选:添加打印函数方便测试 void print() const { if (ptr != nullptr) { cout << ptr << endl; } else { cout << "空字符串" << endl; } } }; // 测试代码 int main() { char str[] = "Hello C++"; myClass obj1(str); obj1.print(); myClass obj2(obj1); obj2.print(); myClass obj3; obj3 = obj1; obj3.print(); return 0; }
额外说明
- 加入空指针判断是为了让代码更健壮,避免传入空指针时直接崩溃。
- 赋值运算符里的自赋值检查很关键,如果没有这一步,当执行
obj = obj时,会先释放自己的内存,后续拷贝时访问已释放的内存,触发未定义行为。 - 深拷贝的核心就是让每个对象拥有独立的内存空间,彻底避免多个对象共享同一块内存带来的重复释放、内存泄漏等问题。
内容的提问来源于stack exchange,提问作者D. D.
相关产品推荐
相关产品推荐

