鱼C论坛

 找回密码
 立即注册
查看: 983|回复: 2

[已解决]重载函数内存释放出错问题

[复制链接]
发表于 2023-3-21 00:34:32 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#include<iostream>
using namespace std;
class  Person
{
public:
        //Person(){}
        ~Person();
        Person(int a, int b, int c) :m_A(a), m_B(b),m_C(new int(c)){ }
        Person operator+(const Person& p);
        Person& operator=(const Person &p);
        bool operator==(const Person & p);
        bool operator!=(const Person &p);
        Person& operator++();  //前置递增
        Person operator++(int); //后置递增7
       

private:
        //friend Person operator+(Person& p1, Person& p2);
        friend ostream& operator<<(ostream& cout, const Person& p);
        int m_A;
        int m_B;
        int* m_C;
};

//~
Person::~Person()
{
        if (this->m_C!=NULL) {
                delete this->m_C;
                this->m_C = NULL;
        }
}


//+
Person Person::operator+(const Person& p)
{
        Person temp(0,0,0);
        temp.m_A = this->m_A + p.m_A;
        temp.m_B = this->m_B + p.m_B;
        if (temp.m_C)
        {
                delete temp.m_C;
                temp.m_C = nullptr;
        }
        temp.m_C = new int(*this->m_C + *p.m_C);
        return temp;
       

}
//=
Person& Person:: operator=(const Person& p)
{
        if (m_C != NULL)
        {
                delete m_C;
                m_C = nullptr;
        }

        m_A = p.m_A;
        m_B = p.m_B;
        m_C = new int(*p.m_C);
        return *this;

}


//+
//Person operator+(Person &p1,Person &p2)
//{
//        Person temp(0,0,0);
//        temp.m_A = p1.m_A + p2.m_A;
//        temp.m_B = p1.m_B + p2.m_B;
//
//        if (temp.m_C)
//        {
//                delete temp.m_C;
//                temp.m_C = nullptr;
//        }
//       
//
//        temp.m_C = new int(*p1.m_C + *p2.m_C);
//        return temp;
//}

//==
bool Person:: operator==(const Person& p)
{
        if (this->m_A==p.m_A&&this->m_B==p.m_B&&*this->m_C==*p.m_C) {

                return true;
        }
        return false;

}
//!=
bool Person::operator!=(const Person& p)
{
        if (this->m_A !=p.m_A&&this->m_B!=p.m_B&&*this->m_C!=*p.m_C ) {
                return true;
        }
        return false;
}

//前
Person&  Person::operator++() //前置递增
{
        this->m_A++;
        this->m_B++;
        (*this->m_C)++;
        return *this;

}


//后
Person  Person::operator++(int) //后置递增
{
        Person temp(this->m_A, this->m_B, *this->m_C);
        this->m_A++;
        this->m_B++;
        (*this->m_C)++;
        return temp;
       

}


//cout
ostream& operator<<(ostream& cout,const Person &p)
{
        cout << p.m_A << "  " << p.m_B << "   " << *p.m_C << "  ";
        return cout;
}




int main()
{
        Person p1(10,100,200);
        Person p2(10, 100,200);
        Person p3(0,0,0);       
        p3 = p1 + p2;
        /*p3=operator+(p1, p2);
        p3 = p2.operator+(p1);
        cout << p3 << endl;

        Person p4(0, 0, 0);
        p4 = p3;
        cout << p4 << endl;

        if (p4 == p3)cout << "相等" << endl;
        else cout << "不相等";

        cout << ++p3;
        cout << p4++;*/



        return 0;
}
调用了+号运算符重载函数出错,我认为可能是浅拷贝问题,于是我释放了temp.m_C,依旧报错了。
最佳答案
2023-3-21 00:40:48
在 operator+ 函数中,你释放了 temp.m_C 并分配了一个新的内存,但是当你将 temp 对象返回时,它是通过拷贝构造函数创建的一个新对象。

这可能导致一个浅拷贝问题,因为新创建的对象和 temp 对象共享相同的 m_C 指针。

当这两个对象的析构函数被调用时,同一块内存会被释放两次,导致内存错误。

要解决这个问题,你需要为 Person 类实现一个拷贝构造函数。拷贝构造函数用于创建一个新对象,并用现有对象的值初始化它。

这样可以确保两个对象有不同的 m_C 指针,避免内存错误。

在 Person 类中添加拷贝构造函数:
class Person
{
public:
    // ...
    Person(const Person &p);
    // ...
};

Person::Person(const Person &p)
{
    m_A = p.m_A;
    m_B = p.m_B;
    m_C = new int(*p.m_C);
}

现在,当 temp 对象从 operator+ 函数返回时,拷贝构造函数会被调用,为新对象创建一个独立的 m_C 指针。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-3-21 00:40:48 | 显示全部楼层    本楼为最佳答案   
在 operator+ 函数中,你释放了 temp.m_C 并分配了一个新的内存,但是当你将 temp 对象返回时,它是通过拷贝构造函数创建的一个新对象。

这可能导致一个浅拷贝问题,因为新创建的对象和 temp 对象共享相同的 m_C 指针。

当这两个对象的析构函数被调用时,同一块内存会被释放两次,导致内存错误。

要解决这个问题,你需要为 Person 类实现一个拷贝构造函数。拷贝构造函数用于创建一个新对象,并用现有对象的值初始化它。

这样可以确保两个对象有不同的 m_C 指针,避免内存错误。

在 Person 类中添加拷贝构造函数:
class Person
{
public:
    // ...
    Person(const Person &p);
    // ...
};

Person::Person(const Person &p)
{
    m_A = p.m_A;
    m_B = p.m_B;
    m_C = new int(*p.m_C);
}

现在,当 temp 对象从 operator+ 函数返回时,拷贝构造函数会被调用,为新对象创建一个独立的 m_C 指针。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2023-3-21 11:40:29 | 显示全部楼层
isdkz 发表于 2023-3-21 00:40
在 operator+ 函数中,你释放了 temp.m_C 并分配了一个新的内存,但是当你将 temp 对象返回时,它是通过拷 ...

//拷贝构造函数
Person::Person(const Person& p)
{
        this->m_A = p.m_A;
        this->m_B = p.m_B;
        /*if (m_C) {
                delete m_C;
                m_C = nullptr;
        }*/
        m_C = new int(*p.m_C);
       
} 为 Person 类实现一个拷贝构造函数进行深拷贝的时候,我发现我不能像赋值运算符重载函数那样释放内存,是否有什么办法可以解释一下拷贝构造在进行深拷贝的时候不能释放内存
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-7 17:32

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表