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

C++ operator=重载后程序运行崩溃问题求助

C++调试崩溃问题:浅拷贝引发的内存错误

问题描述

代码在Dev++中编译通过,但调试运行时崩溃。核心疑惑:想要通过memcpy(array,ar.getArray(),r*c*sizeof(array[0][0]))实现值拷贝(深拷贝),但实际触发了浅拷贝逻辑,导致程序崩溃。

错误现象

运行时触发内存访问错误,程序崩溃(对应原错误截图的崩溃场景)

待排查代码

#include<iostream>
#include<cstdlib>
using namespace std;
class Array2 {
    
    private:
        int r;
        int c;
        int **array;
    public:
        Array2 (){
            cout<<"无参构造函数"<<endl;
            //k=1;
        }
        Array2 (int row,int colume);  
        ~Array2()
        {
            if(array)
            {               
                cout<<"析构函数被调用!"<<endl;
                for(int i=0;i<r;++i)
                {
                    delete [] array[i];
                }
                delete [] array;
                                
            }
    
        }
        int * operator [] (int & i);
        int & operator () (int & i,int & j); 
        Array2 & operator = ( Array2 & ar);

        void setR(int row){
            r=row;
        }
        void setC(int colume){
            c=colume;
        }
                
        int getR()  {
            return r;
        }
        int getC()  {
            return c;
        }
        int** getArray()    {
            return array;
        }                           
};
Array2 & Array2::  operator = ( Array2 & ar){   
    cout<<"赋值运算符重载"<<endl;
    r=ar.getC();
    c=ar.getR();
    array=new int*[r*c];
    for(int i=0;i<r;i++){
        array[i]=new int[c];
    }
    memcpy(array,ar.getArray(),r*c*sizeof(array[0][0]));    
    return *this;   
}

int & Array2:: operator () (int & i,int & j){
    return array[i][j];
}   

int *  Array2:: operator [] (int & i){
    //return a[i];
    return array[i];
}


Array2:: Array2(int row,int colume ):r(row),c(colume)
{   
    cout<<"有参构造函数"<<endl;
    array=new int*[r];
    for(int i=0;i<r;i++){
        array[i]=new int[c];
    }
    
}
int main()
{
    Array2 a(3,4);
    int i,j;
    for(i=0;i<3;++i)
    {
        for(j=0;j<4;j++)
        {
            a[i][j]=i*4+j;
        }
    }
    for(i=0;i<3;++i)
    {
        for(j=0;j<4;++j)
            cout<<a(i,j)<<", ";
        cout<<endl;
    }
    cout<<"next"<<endl;

    Array2 b;
    Array2 c(3,4);
    b=a;
    for(i=0;i<3;++i)
    {
        for(j=0;j<4;++j)
            cout<<b(i,j)<<", ";
    cout<<endl;
    }   
    
    if(&a==&b)
        cout<<"a和b的地址相同"<<endl;
    else
    {
        cout<<"a和b的地址不同"<<endl;
        cout<<"a:"<<a.getArray()<<", "<<"b:"<<b.getArray()<<endl;        
    }

    if(&a!=&c)
        cout<<"a和c的地址不同"<<endl;
    cout<<"a:"<<a.getArray()<<", "<<"c:"<<c.getArray()<<endl;
    return 0;   
}

问题根源与修复方案

1. 赋值运算符的行列值搞反

原代码中r=ar.getC(); c=ar.getR();完全颠倒了行和列的赋值,导致后续内存分配和拷贝逻辑全部错位。
修复:改为r=ar.getR(); c=ar.getC();

2. 二维数组指针数组分配错误

array=new int*[r*c];错误分配了r*c个指针,实际上二维数组的指针数组只需要r个元素(对应每行的起始指针)。
修复:改为array=new int*[r];

3. memcpy误用导致浅拷贝

直接用memcpy拷贝指针数组,会把原对象的每行指针地址复制过来,导致两个对象共享同一片内存区域。程序结束时,两个对象的析构函数会重复释放同一块内存,触发崩溃。
修复:逐行拷贝元素值,替换原memcpy语句:

for(int i=0; i<r; ++i){
    memcpy(array[i], ar.getArray()[i], c*sizeof(int));
}

4. 无参构造未初始化指针

无参构造的array未初始化为nullptr,析构时可能访问野指针。
修复:在无参构造函数中添加array = nullptr;

5. 运算符重载参数的引用问题

operator[]和operator()的参数用int&会导致无法接收临时变量(比如字面量下标),引发编译或运行问题。
修复:改为值传递或const int&,例如:

int * operator [] (int i);
int & operator () (int i,int j);

修正后的赋值运算符重载示例

Array2 & Array2::operator = (Array2 & ar){   
    cout<<"赋值运算符重载"<<endl;
    // 先释放当前对象已有的内存,避免内存泄漏
    if(array){
        for(int i=0;i<r;++i){
            delete [] array[i];
        }
        delete [] array;
    }
    // 正确赋值行列
    r=ar.getR();
    c=ar.getC();
    // 正确分配指针数组
    array=new int*[r];
    for(int i=0;i<r;i++){
        array[i]=new int[c];
        // 逐行拷贝元素值
        memcpy(array[i], ar.getArray()[i], c*sizeof(int));
    }
    return *this;   
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 22:48:51