如何通过类对象访问动态分配内存?矩阵类代码修复求助
问题分析与修正方案
一、核心问题梳理
- 构造函数错误:试图返回指针,且未将动态分配的内存绑定到类成员,导致后续方法无法访问
matrx - 缺少类成员变量:未存储矩阵的行数、列数,也未将
matrx声明为类成员,方法中无法访问矩阵数据 - 方法逻辑错误:
setze_element参数设计不合理,lese_element存在越界风险且错误释放内存 - 未实现拷贝控制:默认拷贝构造/赋值会导致浅拷贝,引发内存泄漏或重复释放
二、修正后的头文件(matrix.h)
#pragma once #include <iostream> class Matrix { private: double* matrx; // 动态分配的矩阵内存(改为double*匹配输入的浮点值) int zeilen_; // 矩阵行数 int spalten_; // 矩阵列数 public: // 带参构造函数:初始化矩阵大小并分配内存 Matrix(int zeilen, int spalten); // 无参构造函数:默认空矩阵 Matrix(); // 拷贝构造函数:深拷贝避免浅拷贝问题 Matrix(const Matrix &m); // 析构函数:释放动态分配的内存 ~Matrix(); // 赋值运算符重载:深拷贝 Matrix& operator=(const Matrix &m); // 设置单个元素的值,参数为行索引、列索引、值,返回1成功,0失败 int setze_element(int zeile, int spalte, double wert); // 读取单个元素的值,参数为行索引、列索引,成功返回值并将erfolg设为1,失败返回0并设erfolg为0 double lese_element(int zeile, int spalte, int &erfolg) const; // 获取行数和列数的getter方法 int zeilen() const { return zeilen_; } int spalten() const { return spalten_; } // 打印整个矩阵的方法 void drucke_matrix() const; };
三、修正后的CPP文件(matrix.cpp)
#include "matrix.h" #include <iostream> #include <cstdlib> // 用于exit和EXIT_FAILURE using namespace std; // 带参构造函数实现 Matrix::Matrix(int zeilen, int spalten) : zeilen_(zeilen), spalten_(spalten) { matrx = new double[zeilen_ * spalten_]; } // 无参构造函数 Matrix::Matrix() : matrx(nullptr), zeilen_(0), spalten_(0) {} // 拷贝构造函数:深拷贝 Matrix::Matrix(const Matrix &m) { zeilen_ = m.zeilen_; spalten_ = m.spalten_; matrx = new double[zeilen_ * spalten_]; for (int i = 0; i < zeilen_ * spalten_; ++i) { matrx[i] = m.matrx[i]; } } // 析构函数 Matrix::~Matrix() { delete[] matrx; matrx = nullptr; // 置空避免野指针 } // 赋值运算符重载:深拷贝 Matrix& Matrix::operator=(const Matrix &m) { if (this == &m) // 防止自赋值 return *this; // 先释放当前对象的内存 delete[] matrx; // 分配新内存并拷贝数据 zeilen_ = m.zeilen_; spalten_ = m.spalten_; matrx = new double[zeilen_ * spalten_]; for (int i = 0; i < zeilen_ * spalten_; ++i) { matrx[i] = m.matrx[i]; } return *this; } // 设置单个元素 int Matrix::setze_element(int zeile, int spalte, double wert) { // 检查索引是否越界 if (zeile < 0 || zeile >= zeilen_ || spalte < 0 || spalte >= spalten_) { return 0; // 越界返回失败 } // 行优先存储的线性索引计算,两种写法等价 // 数组下标写法:matrx[zeile * spalten_ + spalte] = wert; *(matrx + zeile * spalten_ + spalte) = wert; // 指针写法 return 1; // 成功返回1 } // 读取单个元素 double Matrix::lese_element(int zeile, int spalte, int &erfolg) const { erfolg = 0; if (zeile < 0 || zeile >= zeilen_ || spalte < 0 || spalte >= spalten_) { return 0.0; // 越界返回0,erfolg保持0 } erfolg = 1; return *(matrx + zeile * spalten_ + spalte); // 指针写法读取元素 } // 打印整个矩阵的方法 void Matrix::drucke_matrix() const { for (int i = 0; i < zeilen_; ++i) { for (int j = 0; j < spalten_; ++j) { cout << matrx[i * spalten_ + j] << " "; } cout << endl; } } // belegen_m1函数实现 void belegen_m1(Matrix& m) { double cmat[5][3] = { { 1.0, 0.0, 0.0 }, { 0.0, 2.0, 0.0 }, { 0.0, 0.0, 3.0 }, { 4.0, 0.0, 0.0 }, { 0.0, 5.0, 0.0 } }; for (int z = 0; z < m.zeilen(); ++z) { for (int s = 0; s < m.spalten(); ++s) { if (m.setze_element(z, s, cmat[z][s]) == 0) { cout << "Fehler bei belegen_m1(), Abbruch" << endl; exit(EXIT_FAILURE); } } } } int main() { Matrix m1(5,3), m2(3,5); Matrix m3, m4, m5, m6, m7; belegen_m1(m1); m1.drucke_matrix(); // 打印矩阵验证赋值结果 return EXIT_SUCCESS; }
四、关键修正点说明
- 类成员变量补充:新增
matrx(改为double*匹配输入的浮点值)、zeilen_、spalten_作为私有成员,确保所有方法能访问矩阵数据和尺寸。 - 构造函数修正:构造函数不再返回指针,而是初始化成员变量并分配内存;无参构造函数初始化空矩阵。
setze_element方法修正:- 参数改为单个元素的行/列索引,而非整个矩阵的行列数
- 添加索引越界检查,避免非法内存访问
- 线性索引计算正确:
zeile * spalten_ + spalte(行优先存储),指针写法与数组下标写法等价 - 明确返回值:1表示成功,0表示失败
lese_element方法修正:- 功能改为读取单个元素,新增
drucke_matrix方法负责打印整个矩阵 - 移除错误的内存释放操作,内存释放由析构函数统一处理
- 添加越界检查,通过
erfolg参数返回操作状态
- 功能改为读取单个元素,新增
- 拷贝控制实现:完成拷贝构造函数和赋值运算符的深拷贝,避免浅拷贝导致的内存泄漏或重复释放问题
- CPP文件关联修正:添加
zeilen()和spalten()getter方法,让belegen_m1能获取矩阵尺寸;修正代码格式,符合编码规范
内容的提问来源于stack exchange,提问作者Linas
相关产品推荐
相关产品推荐

