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

C++重载+运算符时出现malloc(): corrupted top size内存错误排查

问题描述

我正在编写一个用于矩阵基本运算的C++模板类,近一周来一直受内存问题困扰,每次调用构造函数似乎都会损坏对象。我怀疑+运算符重载存在问题,奇怪的是代码在2x2矩阵下正常运行,但更大的矩阵就会出错。

Matrix类代码

#include<iostream>
#include<stdlib.h>
#include <stdexcept>
#include<cstring>

using namespace std;

template<class TypeData>
class Matrix{

    private: 
    int Nrows , Ncols;
    TypeData *Array_Matrix;

    public:
    /*Constructors---------*/
    Matrix(){
        Nrows = 0;
        Ncols = 0;
        Array_Matrix = nullptr;
    }
    /*Constructor with 2 parameters:*/
    Matrix(int _Nrows , int _Ncols){
        this -> Nrows = _Nrows;
        this -> Ncols = _Ncols;
        Array_Matrix = new TypeData [Nrows * Ncols];
        for(int i = 0 ; i<Nrows * Ncols ; i++){Array_Matrix[i] = 0.0;}
    }
    /*Copy constructor:*/
    Matrix ( const Matrix &_M){
        this -> Nrows = _M.Nrows ; 
        this -> Ncols = _M.Ncols;
        Array_Matrix = new TypeData [Nrows * Ncols];
        for(int i = 0 ; i<Nrows * Ncols ; i++){*(Array_Matrix + i) = *(_M.Array_Matrix + i);}
    }

    void Set_Value(int row , int col , TypeData value){
        *(Array_Matrix  + Ncols*row + col) = value;}
    /*---------------------------------------------------------------------------------------------------------------------*/

    TypeData Get_Pos_Value(int row , int col){
        if(row >= Nrows || col >= Ncols){throw std::invalid_argument( "Error!, index out of bounds!" );}
        else{return *(Array_Matrix + Ncols*row + col) ;}}

    TypeData *Get_Array(){ /*Method for returning a pointer to the "matrix"*/
        return Array_Matrix;};

    int Get_Nrows(){
        return Nrows;}

    int Get_Ncols(){
        return Ncols;}

    void Print_Matrix(){
        for (int i = 0 ; i<Nrows ; i++){
            cout<<endl;
            for (int j = 0 ; j<Ncols ; j++){
                cout<<*(Array_Matrix + Ncols*i + j)<<" ";}}cout<<endl;}

    /*Operator overloading --------------------------------------------------------------------------------------------*/
    Matrix operator = (const Matrix &Matrix_object){

        delete [] Array_Matrix;
        this -> Nrows = Matrix_object.Nrows;
        this -> Ncols = Matrix_object.Ncols;
        Array_Matrix = new TypeData [Nrows * Ncols];

        for (int i = 0 ; i<Nrows*Ncols ; i++){Array_Matrix [i] = Matrix_object.Array_Matrix[i];}

        return *this;
    }

    Matrix operator + (const Matrix &Matrix_object)const{

        if(Matrix_object.Nrows != Nrows || Matrix_object.Ncols != Ncols)
        {throw std::invalid_argument("Different siex matrices cant be added!" );}

        
        Matrix <TypeData> Temp(0,0); Temp.Nrows = Nrows ; Temp.Ncols = Ncols;
        for(int i = 0 ; i<Nrows*Ncols; i++){
                //Temp.Array_Matrix[i] = Array_Matrix[i] + Matrix_object.Array_Matrix[i];
                *(Temp.Array_Matrix +i) = *(Array_Matrix +i) + *(Matrix_object.Array_Matrix + i);} 
                return Temp;}

   Matrix operator - (const Matrix &Matrix_object)const{

        if(Matrix_object.Nrows != Nrows || Matrix_object.Ncols != Ncols)
        {throw std::invalid_argument("Different size matrices can be substracted!" );}

        Matrix <TypeData> Temp(0,0); Temp.Nrows = Nrows ; Temp.Ncols = Ncols;
        for(int i = 0 ; i<Nrows*Ncols; i++){
                //Temp.Array_Matrix[i] = Array_Matrix[i] - Matrix_object.Array_Matrix[i];
                *(Temp.Array_Matrix +i) = *(Array_Matrix +i) - *(Matrix_object.Array_Matrix + i);}

        return Temp;}

    Matrix operator += (const TypeData num){

        Matrix <TypeData> Temp(0,0); Temp.Nrows = Nrows ; Temp.Ncols = Ncols;
            for(int i = 0 ; i<Nrows*Ncols; i++){
                    Temp.Array_Matrix[i] =  Array_Matrix[i]  + num ;} return Temp;}

    Matrix operator -= (const TypeData num){

        Matrix <TypeData> Temp(0,0); Temp.Nrows = Nrows ; Temp.Ncols = Ncols;
            for(int i = 0 ; i<Nrows*Ncols; i++){
                    Temp.Array_Matrix[i] =  Array_Matrix[i]- num ;} return Temp;}

   ~Matrix(){ delete[] Array_Matrix;}
   };

Main函数代码

int main(){
    int r1 , c1; cout<<"Matrix1: Enter Number of rows and columns  "; cin>>r1>>c1;
    Matrix <float> My_Matrix(r1 , c1);

    for (int i = 0 ; i<My_Matrix.Get_Nrows() ; i++){
            for (int j = 0 ; j<My_Matrix.Get_Ncols(); j++){
                float value; cout<<"Type the value at: ["<<i<<"]["<<j<<"] position  "; cin>>value;
                My_Matrix.Set_Value(i , j , value);}}


    int r2 , c2; cout<<"Matrix2: Enter Number of rows and columns   "<<endl; cin>>r2>>c2;
    Matrix <float> My_Matrix2(r2,c2);

    for (int i = 0 ; i<My_Matrix2.Get_Nrows() ; i++){
            for (int j = 0 ; j<My_Matrix2.Get_Ncols(); j++){
                float value; cout<<"Type the value at: ["<<i<<"]["<<j<<"] position  "; cin>>value;
                My_Matrix2.Set_Value(i , j , value);}}


  
    auto My_Matrix3 = My_Matrix + My_Matrix2;
    cout<<"Add:    "<<endl;
    My_Matrix3.Print_Matrix();
    cout<<endl;
    
    cout<<"Testing substraction:    "<<endl;
    auto My_Matrix4 = My_Matrix - My_Matrix2;
    cout<<"Substraction is:  "<<endl;
    My_Matrix4.Print_Matrix();
    cout<<endl; 

    cout<<"Testing = operator:  "<<endl;
    My_Matrix4 = My_Matrix3;
    cout<<"Substraction matriz is now:  "<<endl;
    My_Matrix4.Print_Matrix();
    cout<<endl<<"as the Add matrix! "<<endl;

    cout<<"Testing +=:"<<endl;
    int num ; cout<<"Please enter an integer number:  ";cin>>num;
    (My_Matrix4 += num).Print_Matrix();
    return 0;}

问题分析与修复

核心错误

你代码中的operator+、operator-、operator+=、operator-=存在致命内存问题:

  • 创建Temp(0,0)时,Array_Matrix是默认构造的nullptr
  • 直接修改Temp的行列数但未分配内存,随后访问Temp.Array_Matrix属于空指针解引用,是未定义行为
  • 2x2矩阵时可能恰好未触发崩溃,但大矩阵会覆盖更多非法内存,导致对象损坏

此外还有两个次要问题:

  1. operator=未处理自赋值,若对象赋值给自己,delete[]后会访问已释放的内存
  2. operator+=/operator-=语义错误:这类运算符应修改当前对象而非返回新临时对象

修复后的关键代码

// 修复operator+:直接创建对应大小的临时矩阵
Matrix operator + (const Matrix &Matrix_object)const{
    if(Matrix_object.Nrows != Nrows || Matrix_object.Ncols != Ncols)
    {throw std::invalid_argument("Different size matrices can't be added!" );}

    Matrix <TypeData> Temp(Nrows, Ncols);
    for(int i = 0 ; i<Nrows*Ncols; i++){
        Temp.Array_Matrix[i] = Array_Matrix[i] + Matrix_object.Array_Matrix[i];
    } 
    return Temp;
}

// 修复operator-:同operator+逻辑
Matrix operator - (const Matrix &Matrix_object)const{
    if(Matrix_object.Nrows != Nrows || Matrix_object.Ncols != Ncols)
    {throw std::invalid_argument("Different size matrices can't be subtracted!" );}

    Matrix <TypeData> Temp(Nrows, Ncols);
    for(int i = 0 ; i<Nrows*Ncols; i++){
        Temp.Array_Matrix[i] = Array_Matrix[i] - Matrix_object.Array_Matrix[i];
    }
    return Temp;
}

// 修复operator+=:修改当前对象,返回引用
Matrix& operator += (const TypeData num){
    for(int i = 0 ; i<Nrows*Ncols; i++){
        Array_Matrix[i] += num;
    }
    return *this;
}

// 修复operator-=:同operator+=逻辑
Matrix& operator -= (const TypeData num){
    for(int i = 0 ; i<Nrows*Ncols; i++){
        Array_Matrix[i] -= num;
    }
    return *this;
}

// 修复operator=:增加自赋值检查
Matrix& operator = (const Matrix &Matrix_object){
    if(this == &Matrix_object){
        return *this;
    }

    delete [] Array_Matrix;
    this -> Nrows = Matrix_object.Nrows;
    this -> Ncols = Matrix_object.Ncols;
    Array_Matrix = new TypeData [Nrows * Ncols];

    for (int i = 0 ; i<Nrows*Ncols ; i++){
        Array_Matrix[i] = Matrix_object.Array_Matrix[i];
    }

    return *this;
}

修复说明

  1. 运算符+/-:调用带参数的构造函数创建对应大小的临时矩阵,确保内存已分配
  2. 运算符+=/-=:遵循C++标准语义,直接修改当前对象并返回自身引用,符合用户预期
  3. 赋值运算符:增加自赋值检查,避免释放自身内存后访问非法地址

额外优化建议

  • 用std::copy替代手动循环复制元素(需包含<algorithm>),代码更简洁高效:std::copy(_M.Array_Matrix, _M.Array_Matrix + Nrows*Ncols, Array_Matrix);
  • 构造函数初始化内存时,用new TypeData[Nrows*Ncols]()(加括号)实现值初始化,对复杂类型更安全
  • 避免在头文件中使用using namespace std;,防止命名冲突

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 22:34:58