出现深拷贝浅拷贝问题的原因先提前说明:
一个类或结构体中有指针,由于一个类或者结构体拷贝另外一个类或者结构体,使用了 Peroson p1 = p2; 或者 p1 = p2; 使用了系统默认的拷贝构造函数和等号操作符,这两个方法是使用的值拷贝,将两个对象的指针都指向了一块空间,一个对象释放空间后,另外一个对象再次释放,会导致程序崩掉
看不懂没关系,接下来我用几个例子来解释
class Person
{
public:
//析构函数来释放内存
~Person()
{
if(name != NULL)
{
free(name);
}
name = NULL;
}
public:
char *name;
int age;
};
void Test()
{
Person p1;
p1.name = (char *)malloc(100);
strcpy(p1.name, "吴彦祖");
p1.age = 35;
//调用拷贝构造函数
Person p2 = p1;
//调用=操作符
Person p3;
p3 = p1;
}
int main()
{
Test();
return 0;
}
这就出现了我上述的问题,重复释放内存
毫无疑问,程序挂掉了,我们怎么来解决呢
如果你看懂了上面拷贝产生的原因,一定会知道,只需要把新拷贝的对象的指针重新分配内存即可
下面是代码
class Person
{
public:
Person() {}
//析构函数来释放内存
~Person()
{
if(name != NULL)
{
free(name);
}
name = NULL;
}
Person(const Person& p)
{
//一定要加1 因为strlen不计算最后的'\0' 但是strcpy会在最后一位自动加上'\0'
int len = strlen(p.name)+1;
name = (char *)malloc(len);
strcpy(name, p.name);
age = p.age;
}
Person& operator=(const Person &p)
{
//切记 !! 一定先将原来的内存释放掉
if(name != NULL)
{
free(name);
}
//一定要加1 因为strlen不计算最后的'\0' 但是strcpy会在最后一位自动加上'\0'
int len = strlen(p.name)+1;
name = (char *)malloc(len);
strcpy(name, p.name);
age = p.age;
return *this;
}
public:
char *name;
int age;
};
void Test()
{
Person p1;
p1.name = (char *)malloc(100);
strcpy(p1.name, "吴彦祖");
p1.age = 35;
//调用拷贝构造函数
Person p2 = p1;
//调用=操作符
Person p3;
p3 = p1;
cout << "p1.name:" << p1.name << endl;
cout << "p2.name:" << p2.name << endl;
cout << "p3.name:" << p3.name << endl;
}
int main()
{
Test();
return 0;
}
这样就不会挂掉了。
我第一种示范代码就是使用的浅拷贝,如果有内存分配释放则会挂掉
第二种示范是深拷贝
如果是c语言的结构体,可以自己定义一个函数来拷贝结构体,道理都是一样的
OK 结束