C++动态二维数组拷贝构造问题:拷贝后输出重复内存地址
问题分析与代码修正
你遇到的核心问题是拷贝构造函数和重载赋值运算符只完成了内存分配,没有实际复制原始对象的数据,另外还有几个潜在的内存管理和文件读取问题,我来帮你逐一梳理:
1. 拷贝构造函数的核心缺失:未复制数据
你的拷贝构造函数只是为新对象的Temps二维数组分配了内存,但没有把original对象中的数据拷贝到新数组里。这会导致新创建的拷贝对象里全是未初始化的垃圾值,甚至可能因为内存地址的问题出现你看到的重复输出(如果display函数误打印了指针地址而非数据的话)。
修正后的拷贝构造函数:
Matrix::Matrix(const Matrix & original) { mnumRows = original.mnumRows; mnumCols = original.mnumCols; // 分配行指针数组 Temps = new double*[mnumRows]; for (int row = 0; row < mnumRows; row++) { // 分配每行的内存 Temps[row] = new double[mnumCols]; // 复制该行的每一个元素 for (int col = 0; col < mnumCols; col++) { Temps[row][col] = original.Temps[row][col]; } } }
2. 重载赋值运算符的两个关键问题
问题A:未复制数据
和拷贝构造函数一样,你的赋值运算符只分配了新内存,没有复制second对象的数据,这会导致赋值后的对象数据完全不正确。
问题B:内存释放不彻底
直接delete[] Temps会导致严重的内存泄漏,因为Temps是二维动态数组——你需要先释放每一行的内存,再释放行指针数组本身。
修正后的赋值运算符:
Matrix& Matrix::operator=(const Matrix & second) { // 自我赋值保护 if (this != &second) { // 先释放当前对象的旧内存 // 释放每一行的内存 for (int row = 0; row < mnumRows; row++) { delete[] Temps[row]; } // 释放行指针数组 delete[] Temps; // 复制尺寸信息 mnumRows = second.mnumRows; mnumCols = second.mnumCols; // 分配新内存并复制数据 Temps = new double*[mnumRows]; for (int row = 0; row < mnumRows; row++) { Temps[row] = new double[mnumCols]; for (int col = 0; col < mnumCols; col++) { Temps[row][col] = second.Temps[row][col]; } } } return *this; }
3. readTemps函数的文件读取错误
while (!inFile.eof())是常见的错误写法,因为eof()只有在尝试读取超出文件末尾时才会被设置为true,这会导致最后一行数据被重复读取。正确的做法是把读取操作放在循环条件里:
修正后的readTemps:
void Matrix::readTemps(ifstream &inFile) { for (int row = 0; row < mnumRows; row++) { for (int col = 0; col < mnumCols; col++) { // 把读取操作作为循环条件,读取失败就退出 if (!(inFile >> Temps[row][col])) { return; } } } }
额外建议:添加析构函数
既然使用了动态二维数组,一定要补充析构函数来释放内存,避免长期运行的内存泄漏:
Matrix::~Matrix() { for (int row = 0; row < mnumRows; row++) { delete[] Temps[row]; } delete[] Temps; }
完成这些修正后,你的拷贝构造和赋值运算符就能正确复制数据,应该就能解决你看到的重复输出内存地址(或数据异常)的问题了。
内容的提问来源于stack exchange,提问作者Smith John
相关产品推荐
相关产品推荐

