一、不同方式拷贝出现的问题
最主要出现的问题是,例如结构体当中有一个字符型指针,使用了浅拷贝
两个结构体的字符型指针 free 释放时会报重复释放堆错误,而深拷贝不会。
二、浅拷贝
typedef struct Student {
int id;
char *name;
}st;
void deepShallowCopy()
{
st st1,st2;
st1.id=1;
st1.name=(char*)malloc(10);
st2.name=(char*)malloc(10);
strcpy(st1.name,"张三");
st2=st1;
printf("st1: id:%d name:%s\n",st1.id,st1.name );
printf("st2: id:%d name:%s\n",st2.id,st2.name );
printf("&id:%u &name:%u\n", &st1.id,st1.name );
printf("&id:%u &name:%u\n", &st2.id,st2.name );
if(st1.name!=NULL)free(st1.name);
if(st2.name!=NULL)free(st2.name);
}
注意看14与15行 无论是哪种方法,都是属于浅拷贝 看输出即可找到答案:
st1: id:1 name:张三
st2: id:1 name:张三
&id:151454624 &name:19251216
&id:151454608 &name:19251216
*** Error in `./template': double free or corruption (fasttop): 0x000000000125c010 ***
======= Backtrace: =========
...省略
我们看这个name的地址,通过浅拷贝,st1的name与st2的name指向的是同一块地址空间,因此在释放的时候,会出现多次释放的错误
三、深拷贝
typedef struct Student {
int id;
char *name;
}st;
void deepShallowCopy()
{
st st1,st2;
st1.id=1;
st1.name=(char*)malloc(10);
st2.name=(char*)malloc(10);
strcpy(st1.name,"张三");
memcpy(st2.name,st1.name,strlen(st1.name)+1);
st2.id=st1.id;
printf("st1: id:%d name:%s\n",st1.id,st1.name );
printf("st2: id:%d name:%s\n",st2.id,st2.name );
printf("&id:%u &name:%u\n", &st1.id,st1.name );
printf("&id:%u &name:%u\n", &st2.id,st2.name );
if(st1.name!=NULL)free(st1.name);
if(st2.name!=NULL)free(st2.name);
}
同样的看14与15行,不对整个结构体赋值,而是针对对应的字符串进行拷贝,这样的话st1与st2的name指向的地址是不同的,因此释放也不会出问题。 输出:
st1: id:1 name:张三
st2: id:1 name:张三
&id:1000489904 &name:31944720
&id:1000489888 &name:31944752
三、总结
深浅拷贝总的来说,如果结构体中有指针存在,整个结构体一起赋值就是浅拷贝;单个成员赋值就是深拷贝。
|