You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过类对象访问动态分配内存?矩阵类代码修复求助

问题分析与修正方案

一、核心问题梳理

  • 构造函数错误:试图返回指针,且未将动态分配的内存绑定到类成员,导致后续方法无法访问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;
}

四、关键修正点说明

  1. 类成员变量补充:新增matrx(改为double*匹配输入的浮点值)、zeilen_、spalten_作为私有成员,确保所有方法能访问矩阵数据和尺寸。
  2. 构造函数修正:构造函数不再返回指针,而是初始化成员变量并分配内存;无参构造函数初始化空矩阵。
  3. setze_element方法修正:
    • 参数改为单个元素的行/列索引,而非整个矩阵的行列数
    • 添加索引越界检查,避免非法内存访问
    • 线性索引计算正确:zeile * spalten_ + spalte(行优先存储),指针写法与数组下标写法等价
    • 明确返回值:1表示成功,0表示失败
  4. lese_element方法修正:
    • 功能改为读取单个元素,新增drucke_matrix方法负责打印整个矩阵
    • 移除错误的内存释放操作,内存释放由析构函数统一处理
    • 添加越界检查,通过erfolg参数返回操作状态
  5. 拷贝控制实现:完成拷贝构造函数和赋值运算符的深拷贝,避免浅拷贝导致的内存泄漏或重复释放问题
  6. CPP文件关联修正:添加zeilen()和spalten() getter方法,让belegen_m1能获取矩阵尺寸;修正代码格式,符合编码规范

内容的提问来源于stack exchange,提问作者Linas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 19:07:05