文章下方附学习资源,自助领取 最近在做通信协议的解析处理、传递分析的时候,总是遇到通信帧中的结构体拷贝等问题,而这些问题也是比较基础又易错的C语言知识。今天,我们探究一下结构体的深拷贝和浅拷贝。浅拷贝 C语言中的浅拷贝是指在拷贝过程中,对于指针型成员变量只拷贝指针本身,而不拷贝指针所指向的目标,它按字节复制的。 接下来,我们分几种情况举例来看一下。1、结构体中不存在指针成员变量时 代码如下:在win1064位vs2017来源:技术让梦想更伟大作者:李肖遥includestdio。htypedefstruct{charname〔64〕;intage;}Member;intmain(){Memberstu1{LiMing,18};Memberstu2;stu2stu1;printf(s,d,stu2。name,stu2。age);system(pause);return0;} 运行如下: 点击获取1V1嵌入式学习规划,现在还送100G精选学习资料。鍜瀛範宓屽叆寮忕墿鑱旂綉寮鍙 2、结构体中存在指针成员变量时 代码如下:在win1064位vs2017来源:技术让梦想更伟大作者:李肖遥includestdio。hincludestdlib。hincludestring。htypedefstruct{charname;intage;}Member;intmain(){MemberMember1,Member2;Member1。namemalloc(sizeof(char)64);if(NULLMember1。name){printf(mallocfailed);}memset(Member1。name,0,64);strcpy(Member1。name,LiMing);snprintf(Member1。name,64,LiMing);Member1。age18;Member2Member1;拷贝snprintf(Member2。name,64,LiXiaoYao);Member2。age29;printf(s,d,Member1。name,Member1。age);if(NULL!Member1。name){free(Member1。name);Member1。nameNULL;}system(pause);return0;} 运行如下: 从中我们看到,改变Member2的值,Member1的值也改变了,这说明一片空间被两个不同的子对象共享了,改变一个对象的值另外一个也会随之改变。 我们改变Member2写法,申请内存的代码如下:在win1064位vs2017来源:技术让梦想更伟大作者:李肖遥includestdio。hincludestdlib。hincludestring。htypedefstruct{charname;intage;}Member;intmain(){MemberMember1;Member1。namemalloc(sizeof(char)64);if(NULLMember1。name){printf(mallocfailed);}memset(Member1。name,0,64);strcpy(Member1。name,LiMing);snprintf(Member1。name,64,LiMing);Member1。age18;MemberMember2;Member2。namemalloc(sizeof(char)64);if(NULLMember2。name){printf(mallocfailed);}memset(Member2。name,0,64);strcpy(Member2。name,LiMing);snprintf(Member2。name,64,LiXiaoYao);Member2。age29;Member1Member2;printf(s,d,Member2。name,Member2。age);if(NULL!Member1。name){free(Member1。name);Member1。nameNULL;}if(NULL!Member2。name){free(Member2。name);Member2。nameNULL;}system(pause);return0;} 运行如下: 从中我们看到,当数据成员中有指针时,两个类中的两个指针将指向同一个地址,当对象快结束时,会调用两次free函数,此时Member2已经是野指针(图中有X的错误标志),这个野指针指向的内存空间已经被释放掉,再次释放会报异常错误,要解决这个问题就要涉及到深拷贝了。深拷贝 深拷贝除了拷贝其成员本身的值之外,还拷贝成员指向的动态内存区域内容,深拷贝会在堆内存中另外申请空间来储存数据。 解决的思路是在释放掉被赋值指针变量的旧指向内存时,重新对其开辟新内存,这种情况下两个结构体中指针地址不同,但是指向的内容是一致的。 代码如下:在win1064位vs2017来源:技术让梦想更伟大作者:李肖遥includestdio。hincludestdlib。htypedefstruct{charname;intage;}Member;intmain(){MemberMember1;Member1。namemalloc(sizeof(char)64);if(NULLMember1。name){printf(mallocfailed);}memset(Member1。name,0,64);strcpy(Member1。name,LiMing);snprintf(Member1。name,64,LiMing);Member1。age18;MemberMember2;Member2。namemalloc(sizeof(char)64);if(NULLMember2。name){printf(mallocfailed);}memset(Member2。name,0,64);strcpy(Member2。name,LiMing);snprintf(Member2。name,64,LiXiaoYao);Member2。age29;if(Member1。name!NULL){free(Member1。name);Member1。nameNULL;}Member1。namemalloc(strlen(Member2。name)1);strcpy(Member1。name,Member2。name);printf(s,d,Member1。name,Member1。age);if(NULL!Member1。name){free(Member1。name);Member1。nameNULL;}if(NULL!Member2。name){free(Member2。name);Member2。nameNULL;}system(pause);return0;} 运行如下: 结论 使用C语言来说,深拷贝浅拷贝的概念我们不需要深究,在进行结构体拷贝的时候,结构体成员是非指针的话,那么直接赋值是没有任何问题的,建议使用这种方式,避免浅拷贝这类不易发现的错误产生。 如果成员有指针类型,我们就需要重写拷贝函数,自己定义拷贝行为了,这一点我们需要尤为注意。 END 文章来源于技术让梦想更伟大,作者李肖遥 本文转载自嵌入式微处理器,如有侵权,请联系删除 原文链接:C语言结构体成员赋值的深拷贝与浅拷贝 版权声明:本文来源网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。