结构体及其应用:结构体的深度拷贝,结构体内含指针
来源:互联网 发布:java解析xml文件 编辑:程序博客网 时间:2024/05/22 22:22
1、在前一篇文章中提到,尽量不要使用赋值操作符来操作结构体,这其中所涉及的便是结构体的深度拷贝。
对于下面这个例子:
struct teacher{ char szName[24]; int age; double income;}
进行以下的操作:
struct t1,t2;strcpy(t1.szName,"Lucy");t1.age =24;t1.income = 10789.4;t2=t1;
</pre><pre name="code" class="cpp" style="background-color: rgb(255, 255, 255);">
<pre name="code" class="cpp" style="background-color: rgb(255, 255, 255);">上述操作不会出现任何的问题,程序也会达到我们预期的目的。但是对于下面的例子呢:
<pre name="code" class="cpp">struct teacher{ char *pName; int age; double income;}我们进行如下的操作:
<pre name="code" class="cpp">struct teacher t1,t2;t1.pName = (char*)malloc(24*sizeof(char));memset(t1.pName,0,24*sizeof(char));strcpy(t1.pName,"Lily");t1.age = 23;t1.income = 9877.4;t2 = t1;
乍看之下,似乎没有什么问题。但是这只是程序的一部分,在程序中进行了内存的分配,t1.pName = (char*)malloc(24*sizeof(char));
现在执行赋值运算符,使得t2和t1有相同的内容,此时t2.pName 和 t1.pName指向相同的内存空间。我们知道动态分配的内存需要通过free(C语言中)来释放掉,否则会出现内存泄露。
我们执行下面的操作:
if( NULL!= t1.pName){ free(t1.pName); t1.pName = NULL;//释放之后立即置空,防止出现悬垂指针}
此时我们将给t1的pName分配的内存空间释放掉之后,t2.pName 便指向了一块不存在的内存空间,此时t2.pName 的行为便是未定义的,如果强行对t2.pName 进行操作,会引起程序的崩溃,那么我们该如何来操作呢?
2、结构体的深度拷贝
首先看一个例子:
#include "stdlib.h"#include "stdio.h"#include "string.h"//结构体的定义typedef struct _AdvTeacher{char *name;char buf[100];int age;}Teacher ;Teacher * creatT(){Teacher *tmp = NULL;tmp = (Teacher *)malloc(sizeof(Teacher));tmp->name = (char *)malloc(100);if (NULL == tmp->name){printf("%s","内存分配失败!");return NULL;}tmp->age = 23;strcpy_s(tmp->name, 100, "Lucy");strcpy_s(tmp->buf, 100, "Huazhong University of science and technology");return tmp;}void display_Teacher(Teacher *pTeacher){if (NULL == pTeacher){printf("%s", "NULL Object");return;}printf("name:%s,age:%4d ,buf:%s", pTeacher->name, pTeacher->age, pTeacher->buf);printf_s("name::%s", pTeacher->name);printf("HelloWorld!");} void FreeT(Teacher *t){if (t == NULL){return ;}if (t->name != NULL){free(t->name);}}void copyObj(Teacher *to, Teacher *from){//*to = *from;//copy;to->name = (char *)malloc(100);if (NULL == to->name){printf("%s", "内存分配失败!");return;}strcpy_s(to->name,200, from->name);to->age = from->age;strcpy_s(to->buf, 100, from->buf);}void mainError(){Teacher *t1;Teacher t2;t1 = creatT();copyObj(&t2, t1);//printf_s("%s","t1 Content:");display_Teacher(t1);//printf("\n%s", "t2 Content:");display_Teacher(&t2);FreeT(t1);FreeT(&t2);//}
程序运行的结果如图所示
解释一下这个程序:
createT();函数来创建Teacher对象,并且在createT()内部分配内存空间。copyTeacher()用来执行深度拷贝,给t2.pName()分配内存空间,并且将t1中的内容拷贝给t2。
最后分配的内存空间通过freeT();来释放掉,避免内存泄露的发生。
所以我们一定要避免对结构体内部嵌套指针时使用赋值操作符,因为在C语言中没有提供操作符重载,所以我们不能给赋值操作符以新的含义,在C语言中我们只能不断提高自己的编程技巧来避免这样的问题的产生。
0 0
- 结构体及其应用:结构体的深度拷贝,结构体内含指针
- 结构体内的指针
- 结构体及其应用:认识结构体
- 结构体成员地址在结构体内的偏移
- C++结构体内的结构体如何初始化
- 结构体的使用以及结构体内存对齐
- 指针组合(如指针数组)的区分及其结构体内存大小的计算
- 结构体内嵌一级指针
- 结构体数组及其应用
- 结构体内存分布,指针,指针的指针。
- 指向结构体数组的指针应用
- 结构体指针的应用理解
- 函数 指针 结构体的综合应用
- 指向结构体的指针数组,应用
- 结构体struct的应用、结构体变量、结构体指针变量、结构体指针变量类型的区别
- C语言 结构体的应用 查询结构体中的信息 结构体与指针操作
- 结构体变量、结构指针变量、结构数组作为函数的参数应用实例分析
- 结构体变量、结构指针变量、结构数组作为函数的参数应用实例分析
- iphone开发中的一些小技巧
- httpcore和httpclient的源码一点点(1)
- 算法——分治算法
- c#入门
- 常用工具
- 结构体及其应用:结构体的深度拷贝,结构体内含指针
- Ubuntu系统的安装与使用:搜狗输入法安装
- 动画特效十六:网易新闻之“排序删除”效果
- 读取web.config中单个节点的方法 (读取xml文件的方法测试完毕,成功)
- OC基础之 ---------- block / 代理模式 ,协议 /
- STM32F407VG的DCMI-OV7670和FSMC-LCD
- iOS 开发知识点
- git学习二:git初级使用教程
- Android 开机自启动示例程序