C/C++中的深拷贝浅拷贝问题

出现深拷贝浅拷贝问题的原因先提前说明:

    一个类或结构体中有指针,由于一个类或者结构体拷贝另外一个类或者结构体,使用了 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 结束

猜你喜欢

转载自blog.csdn.net/qq_33413868/article/details/80781066