gegege123gege
2016-03-10 01:13
采纳率: 43.8%
浏览 1.5k

C++ 操作符重载的内存释放问题

=操作符重载,给复构造函数进行赋值时的代码如下:

MyString & MyString::operator =(const MyString &str)
{
if(this == &str)
return *this;

    delete []m_pData;    //**???????????????????????????? **
    m_pData = NULL;

    m_pData = new char(strlen(str.m_pData) + 1);
    strcpy (m_pData, str.m_pData);

    return *this;

}

class MyString
{
public:
....
private:
char *m_pData;
}

在函数中为什么还要是对原有的内存进行释放,即delete []m_pData,直接赋值 m_pData = str.m_pData, 这样不行吗?

请大神指点。

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

4条回答 默认 最新

  • cxsmarkchan 2016-03-10 01:31
    已采纳

    有两个问题:
    1. 如果不delete,那么m_pData重新赋值后,原先指向的的内存不能被访问,也没有被回收给程序继续使用,相当于你的内存就减小了一块,也就是内存泄漏。
    2. 不管是否delete,执行m_pData = str.m_pData都是错误的。因为这样,两个指针指向的是同一片地址,例如你执行str1 = str2,如果按你的方式来实现,那么以后修改str2中的字符串时,由于str1中的m_pData也指向同一片区域,因此str1中的字符串也会被修改。一般来说,这不是我们希望看到的结果。
    类似于这样:

    int a = 1, b = 2;
    a = b;
    b = 3;
    

    那么我们希望此时a的值等于2,而不是3。如果执行了b = 3之后,a的值也变成了3,那自然是不符合预期的。

    已采纳该答案
    打赏 评论
  • bdmh 2016-03-10 01:24

    赋值后,就指向了新的对象,那原来的对象中分配的空间就造成了了内存泄露,所以先释放

    打赏 评论
  • 小灸舞 2016-03-10 01:25

    原有的内存空间与新赋值的内存空间长度有可能不一致。如果新赋值的内存空间长度大于原有的内存空间长度,需要重新开辟空间存储。所以需要现删除原有的内存空间,然后重新分配内存空间。否则有可能造成内存泄露。

    打赏 评论
  • John_ToDebug 2016-03-10 04:34

    #if 1
    class MyString
    {
    public:
    MyString(){}
    MyString(char str)
    {
    if (NULL == str)
    {
    m_pData = new char[1];
    m_pData[0] = '\0';
    }
    else
    {
    m_pData = new char[strlen(str) + 1];
    strcpy_s(m_pData, strlen(m_pData), str);
    }
    }
    MyString & operator =(const MyString &str);
    char
    Print()
    {
    return m_pData;
    }

    ~MyString()
    {
        delete[]m_pData;
        m_pData = NULL;
    }
    

    private:
    char *m_pData;
    };

    MyString & MyString::operator =(const MyString &str)
    {
    if (this == &str)
    return this;
    //delete[]m_pData; //
    *???????????????????????????? **
    //m_pData = NULL;

    //m_pData = new char(strlen(str.m_pData) + 1);
    //strcpy_s(m_pData, strlen(m_pData), str.m_pData);
    m_pData = str.m_pData;
    return *this;
    

    }

    int main()
    {
    MyString str1 = "asd";
    MyString str2;
    str2 = str1;
    cout << str2.Print() << endl;
    return 0;
    }
    #endif

    图片说明
    其一,浅拷贝只是拷贝了指针,使得两个指针指向同一个地址,这样在对象块结束,调用函数析构的时,会造成同一份资源析构2次,即delete同一块内存2次,造成程序崩溃。
    其二,浅拷贝使得obj.m_data和obj1.m_data指向同一块内存,任何一方的变动都会影响到另一方。
    其三,在释放内存的时候,会造成obj1.m_data原有的内存没有被释放(这句话,刚开始我不太理解,如果没有走自定义的拷贝构造函数,申请内存空间,A obj1(obj);也不走默认构造函数,走的是默认的拷贝构造函数,何来分配空间直说,更不会造成obj1.m_data原有的内存没有被释放,这里刚开始我一直有疑问),造成内存泄露。
    事实是这样的,当delete obj.m_data, obj.m_data内存被释放后,由于之前obj.m_data和obj1.m_data指向的是同一个内存空间,obj1.m_data所指的空间不能在被利用了,delete obj1.m_data也不会成功,一致已经无法操作该空间,所以导致内存泄露。

    打赏 评论

相关推荐 更多相似问题