首页 > 代码库 > 结构体知识梳理4-浅拷贝深拷贝

结构体知识梳理4-浅拷贝深拷贝

应用场景分析,我们希望对一个学生的信息做备份

代码一

typedef struct student{
	int num; 
	int age;
	char name[10];
}s_stu,*p_stu;
//stu1  stu2 有独立的内存空间,存储 num  age  name
s_stu stu1;
s_stu stu2;
stu1.num = 1;
stu1.age = 1;
strcpy(stu1.name,"lilei");
//以下做的是memcpy(&stu2,&stu1,sizeof(s_stu))
stu2 = stu1;
printf("stu2.num = %d",stu2.num);
printf("stu2.age = %d",stu2.age);
printf("stu2.name = %s",stu2.name);

stu1 和stu2分别有两个char  name[10]数组存储字符串


以上代码,stu1 ,stu2 分别存储一份学生的信息,可以实现学生信息的备份

我们画内存图如下:



对于以上代码来说,用数组存储姓名,这样字符串的最大长度已经固定,如果字符串长度超过数组长度,则会出现问题。


代码二

因此我们需要根据字符串的长度来动态分配内存空间,我们定义以下结构体

typedef struct student{
	int num; 
	int age;
	char *name;
}s_stu,*p_stu;

我们写以下测试代码

char *buff = "lilei";//需要存储的学生的名字
s_stu stu1;
s_stu stu2;

stu1.num = 1;
stu1.age = 1;
stu1.name = malloc(strlen(buff))+1;//根据字符窜长度来分配相应内存。
strcpy(stu1.name,buff);

//以下做的是memcpy(&stu2,&stu1,sizeof(s_stu))
stu2 = stu1;
printf("stu2.num = %d",stu2.num);
printf("stu2.age = %d",stu2.age);
printf("stu2.name = %s",stu2.name);
//到这里打印没有问题。
到此,我们画内存图如下:


注意这里并没有把 名字复制一份存储下来,而只是stu2.name 指针 和 stu1.name 指针存储了同一个地址,如果一旦 free(stu1.name),则这时候stu2.name也不能使用了,并没有把字符串复制存储下来,这种现象叫做浅拷贝。

我们希望对学生的有效信息有两份,因此内存图应该是如下:



这种现象叫做深拷贝。

根据以上需求我们写代码如下

//假定能够复制的前提是 src 已经存储了学生信息
void stucpy(p_stu dest,const p_stu src)
{
	int len = 0;
	//检查dest ,src 不为null
	//检查src->name 不为null
	len = strlen(src->name)+1;
	//这里为什么要释放?
	if(dest->name!=NULL)
	{
		free(dest->name);
	}
	dest->name = (char*)malloc(len);
	//检查dest->name 不为null
	strcpy(dest->name,src->name);
	dest->num = src->num;
	dest->age = src->age;

}

以上代码请大家分析补充完整。