为何C++中拷贝IntegerArray对象会触发Core Dump?
问题:拷贝IntegerArray对象触发Core Dump(double free)
问题重现
以下是实现的IntegerArray类及测试代码:
class IntegerArray { public: int *data; IntegerArray() { data = new int[1]; } IntegerArray(int len) { data = new int[len]; } ~IntegerArray() { delete data; } }; int main() { IntegerArray a(2);//This call the constructor a.data[0] = 4; a.data[1] = 2; if (true) IntegerArray b = a; printf("%d\n", a.data[0]); }
运行后触发Core Dump,输出如下:
0 free(): double free detected in tcache 2 Aborted (core dumped)
核心原因
- 默认拷贝构造函数的浅拷贝:执行
IntegerArray b = a时,C++自动生成的默认拷贝构造函数只会复制成员变量,导致b.data和a.data指向同一块堆内存。 - 重复释放内存:
b离开if作用域时,析构函数释放该内存;main结束时a的析构函数再次释放同一块内存,触发double free错误。 - 非法内存访问:
b析构后a.data指向的内存已被释放,此时访问a.data[0]属于非法操作,输出的0是随机垃圾值。 - 析构函数的错误:原代码用
delete data释放new[]分配的数组,属于C++未定义行为,正确做法是用delete[] data。
解决方案:实现深拷贝(遵循三/五法则)
手动实现拷贝构造函数和拷贝赋值运算符,为新对象分配独立堆内存并复制数据(深拷贝),同时修正析构函数,添加数组长度成员记录内存大小。
修改后的完整代码:
class IntegerArray { public: int *data; int m_len; // 添加成员变量,记录数组长度 IntegerArray() { m_len = 1; data = new int[m_len]; } IntegerArray(int len) { m_len = len; data = new int[m_len]; } // 拷贝构造函数:深拷贝 IntegerArray(const IntegerArray& other) { m_len = other.m_len; data = new int[m_len]; // 复制原数组的所有元素 for (int i = 0; i < m_len; ++i) { data[i] = other.data[i]; } } // 拷贝赋值运算符:深拷贝 IntegerArray& operator=(const IntegerArray& other) { if (this != &other) { // 防止自赋值导致内存泄漏 // 先释放当前对象已有的内存 delete[] data; // 分配新内存并复制数据 m_len = other.m_len; data = new int[m_len]; for (int i = 0; i < m_len; ++i) { data[i] = other.data[i]; } } return *this; } ~IntegerArray() { delete[] data; // 用delete[]释放数组内存 } }; int main() { IntegerArray a(2); a.data[0] = 4; a.data[1] = 2; if (true) IntegerArray b = a; printf("%d\n", a.data[0]); // 此时输出4,程序正常结束 }
内容的提问来源于stack exchange,提问作者loaded_dypper
相关产品推荐
相关产品推荐

