• 所谓浅拷贝就是编译器机械的拷贝变量1中的内容到变量2中,如果是指针变量只会拷贝指针变量中存放的地址并不会拷贝指针所指向的内存空间的内容
  • 深拷贝需要自己实现拷贝指针所指向的内存空间的内容
  • 编程时不知道浅拷贝与深拷贝的关系可能会出现一些很难发现的错误
    浅拷贝
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct student
{char name[32];char *_name;int age;
};struct student *Creat_student(int count)
{int i=0;struct student *stutemp=(struct student *)malloc(count*sizeof(struct student ));if(stutemp==NULL){printf("分配内存失败!!!\n");return NULL;}for(i=0;i<count;i++){memset(&stutemp[i],0,sizeof(struct student));stutemp[i]._name=(char *)malloc(32);memset(stutemp[i]._name,0,32);}return stutemp;
}void free_student(struct student *stu)
{if(stu==NULL){printf("stu==NULL");return ;}if(stu->_name!=NULL){free(stu->_name);}free(stu);
}int main()
{int num=1;struct student *Stu1=NULL;struct student *Stu2=NULL;Stu1=Creat_student(num);Stu2=Creat_student(num);Stu1->age=20;strcpy(Stu1->name,"321");strcpy(Stu1->_name,"123");Stu2=Stu1;//等号操作编译器会执行浅拷贝机械的拷贝变量Stu1中的内容到变量Stu2中free_student(Stu1);free_student(Stu2);//因为是浅拷贝 这样干相当于把同一块内存释放两遍程序会崩溃return 0;
}

程序运行时直接崩溃,我们可以分析一下他的内存Stu1和Stu2是指针变量分配四个字节在栈区,经过Creat_student(num)函数后指向堆区分配的内存,在Creat_student(num)函数中又为*_name分配了空间不难画出内存图
在执行Stu2=Stu1后编译器并没有将Stu1所指向的内存空间数据拷贝给Stu2,而是直接将Stu1中所存的地址拷贝给Stu2,导致Stu2指向Su1所指的内存空间释放两次自然会导致程序崩溃。
如果将Stu2=Stu1改为*Stu2=*Stu1,程序同样会崩溃,这是因为Stu1->_name直接指向了Stu1->_name 所指向的内存
深拷贝

void deep_copy(struct student *stu1,struct student *stu2)//深拷贝
{memcpy(stu1,stu2,sizeof(struct student ));//先执行浅拷贝拷贝数据stu1->_name=(char *)malloc(32);memcpy(stu1->_name,stu2->_name,32);
}

深拷贝只需将Stu1=Stu2;改为deep_copy(Stu2,Stu1);这样相当于手工给他拷贝了指针所指向内存空间的值,程序可以正常运行。

结构体中的浅拷贝与深拷贝相关推荐

  1. c语言给结构体指针申请空间,结构体中的指针变量申请空间问题

    本人声明了一个结构体包含id,age,name三个属性 struct studentInfo { int id; int age; char *name[20]; }; 本人又创建了一个双向循环链表, ...

  2. 获取结构体中变量的偏移量

    C/C++获取结构体中变量的偏移量 1.某些特殊需求下,我们需要知道某个变量在其结构体中的偏移位置. 通常的做法就是定义一个宏变量,如下: #define OFFSET(structure, memb ...

  3. 结构体中定义函数指针

    结构体指针变量的定义,定义结构体变量的一般形式如下: 形式1:先定义结构体类型,再定义变量 struct结构体标识符 { 成员变量列表;- }; struct 结构体标识符 *指针变量名; 变量初始化 ...

  4. 结构体中最后一个成员为[0]或[1]长度数组(柔性数组成员)的用法

    结构体中最后一个成员为[0]长度数组的用法:这是个广泛使用的常见技巧,常用来构成缓冲区.比起指针,用空数组有这样的优势:(1).不需要初始化,数组名直接就是所在的偏移:(2).不占任何空间,指针需要占 ...

  5. 【C语言】宏offsetof的模拟实现 (计算结构体中某变量相对于首地址的偏移)

    首先我们应该特别留意 : offsetof 是一个宏,并非是一个函数 ! 宏offsetof的介绍 : 参数:第一个是结构体类型名称,第二个是结构体成员名 返回类型:size_t无符号整形 引用的头文 ...

  6. 结构体中string类型成员

    结构体中存在string类型成员 原创 2015年12月21日 17:34:04 标签: 结构体 / string类型成员 / 构造函数 2593 #include <iostream> ...

  7. malloc和free——结构体中动态内存的管理

    C语言中内存的管理主要是依据malloc和free实现的,其中malloc主要是实现内存的分配,而free则是实现内存的释放.虽然这是我们已经很熟悉的,但是还是存在一些问题.特别是当结构体中存在指针的 ...

  8. 【Linux 内核 内存管理】Linux 内核堆内存管理 ① ( 堆内存管理 | 内存描述符 mm_struct 结构体 | mm_struct 结构体中的 start_brk、brk 成员 )

    文章目录 一.堆内存管理 二.内存描述符 mm_struct 结构体 三.mm_struct 结构体中的 start_brk.brk 成员 一.堆内存管理 Linux 操作系统中的 " 堆内 ...

  9. 【C 语言】结构体 ( 结构体中嵌套二级指针 | 为 结构体内的二级指针成员 分配内存 | 释放 结构体内的二级指针成员 内存 )

    文章目录 一.结构体中嵌套二级指针 1.结构体中嵌套二级指针 类型声明 2.为 结构体内的二级指针成员 分配内存 3.释放 结构体内的二级指针成员 内存 二.完整代码示例 一.结构体中嵌套二级指针 1 ...

最新文章

  1. 2.Spring初学
  2. python调用C++之pybind11入门
  3. c++学习书籍推荐《Visual C++2008入门经典》下载
  4. arcgis字段计算器赋值_ARCGIS操作技巧总结
  5. long 雪花算法_雪花算法
  6. [reference]-ARM缩写
  7. Androi App缓存管理
  8. matlab 6.5 设计数字滤波器
  9. Design Compiler指南——后综合过程
  10. c++11 string u8_深入理解C++11:C++11新
  11. Linux内核配置系统浅析
  12. 火爆全网的迁移学习简明手册全面更新,重磅出版上市!
  13. mysql 与c_mysql基础:mysql与C结合实例
  14. 磁盘位置_ORACLE RAC ASM磁盘组迁移到新的ASM磁盘组方法
  15. m7405d粉盒清零方法_联想m7605d清零方法
  16. HTTP请求中文乱码解决办法
  17. zuc算法代码详解_ZUC祖冲之序列密码算法
  18. Python地理地图可视化:plotly连接mapbox多个地理经纬度中心点line+marker
  19. ie浏览器自动清理缓存简单设置方法
  20. 谈谈对儒家与道家的一些小小看法

热门文章

  1. MySQL基数(索引基数)
  2. java list遍历添加元素_java 遍历中为对象添加元素
  3. java的list遍历_【java】list集合遍历的5种方式
  4. RNN:深度学习噪声抑制(初体验)
  5. [PyQt]使用Qt Designer设计师完成PyQt界面图标设计
  6. jxse2.6连接外网rdv一直连接不上,而相同的代码用jxse2.7却能连上
  7. Visual stdio2015的安装以及如何编写第一个C代码
  8. Java根据txt文件数据得到list_java中如何将一个txt文件中的数字读取到一个ArrayList集合中?...
  9. JRTHW跳闸合闸监视继电器
  10. EMO-DB 数据集的 Speech 特征提取