欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > PPT文档下载  

    C语言动态分配内存课件.ppt

    • 资源ID:1480401       资源大小:2.23MB        全文页数:62页
    • 资源格式: PPT        下载积分:16金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要16金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    C语言动态分配内存课件.ppt

    1动态内存分配基础2动态内存分配实例3动态内存分配进阶,C语言动态分配内存,1,t课件,动态分配内存基础,2,t课件,动态分配内存概述,什么时候需要动态分配内存?实例:顺序对一批文件进行解析,但是不知道文件的大小,如何建立缓冲区?,3,t课件,malloc函数,malloc函数原型:void * malloc(size_t n);n是要分配的内存的大小,返回值是分配内存的块的首地址,4,t课件,malloc函数,例1:使用malloc函数分配一个可以容纳10个整型元素的内存空间,并将其用作一个整型数组,5,t课件,malloc函数,关键代码:int * array;array = (int *)malloc(10 * sizeof(int);注意:内存大小不能写成数组元素的个数,6,t课件,malloc函数,例2:定义一个结构struct testint a;char b;int c10;使用malloc函数分配一个此种结构类型的对象,7,t课件,malloc函数,关键代码:struct test * p;p = (struct test *)malloc(sizeof(struct test);,8,t课件,需要注意的问题,(1)malloc函数是一个库函数,它并不是C语言中的关键字:需要头文件才可以使用该函数并不是所有的平台都可以使用该函数,尤其是一些单片机系统,9,t课件,需要注意的问题,(2)指针类型转换是必须的,关系到接收分配好的内存块的地址可以向前看多少字节。如果不做指针类型转换会怎么样?void * 指针存在的意义。,10,t课件,需要注意的问题,(3)内存块大小的可移植性问题分配一个整型变量数组应使用:数组元素个数 * sizeof(int)确定内存块的大小问题:sizeof和strlen函数的区别,11,t课件,free函数,free函数原型:void free(void * p);p是要释放的已分配内存的块的首地址,12,t课件,free函数,释放一块动态分配的内存:例如:int *p;p = (int *)malloc(sizeof(int);free(p);,13,t课件,需要注意的问题,(1)free函数同样是一个库函数(2)free函数的参数必须是一个由动态内存分配方法分配的内存块的首地址(使用malloc函数分配的内存),14,t课件,动态分配内存特点,内存空间大小可以是一个变量,其值在运行时确定内存空间在运行时分配,在程序结束时收回;内存的分配由操作系统参与完成动态分配的内存空间在未释放之前均可以被引用,保证其生命期,15,t课件,链表,16,t课件,链表的概述,struct node int node; /* 数据域,存储结点的值 */struct node * next;,17,t课件,链表示意图,value1,value 2,value 3,value 4,NULL,18,t课件,处理链表使用的函数,动态申请内存:void * malloc(size_t n);释放动态内存:void free(void *);,19,t课件,插入一个结点,struct node *p = /* 连接b结点和c结点 */,20,t课件,删除一个结点,struct node *p = /* 摘下的b结点一定要释放掉*/,21,t课件,动态内存分配实例,22,t课件,动态内存分配实例,设计一个学生链表,其每个结点是一个学生信息的集合。每个结点包含如下信息:学生姓名、学号、C语言成绩三项。初始时拥有3个学生,添加一个学生(使用一个函数实现此操作),再删除一个学生(使用另一个函数实现此操作),并打印该学生的信息。,23,t课件,实例关键点分析,结点结构:struct infochar name10;int id;int score;struct stdstruct info;struct std * next;,24,t课件,实例关键点分析,main函数:int main(void)/* 初始化学生链表 */* 插入一个学生信息结点 */* 删除一个学生的信息,并且打印 */return 0;,25,t课件,实例关键点分析,int insert(char * name, int id, int score)/* 分配一个struct std结构对象 */* 将参数赋值到结构对应的成员中 */return 1; /* 正确完成操作,返回1 */,26,t课件,实例关键点分析,int remove(int id, struct std * res)/* 根据id找到该学生的信息结点 */* 将该结点从链表上取下 */* 使用res保存该节点 */* 释放该结点所占用的内存 */return 1; /* 成功操作返回1 */,27,t课件,综合实例,(1)实现print函数对其遍历打印链表(2)实现destroy函数释放每一个链表节点(3)实现search函数查找链表中的元素(4)实现一个升级版的insert将元素按顺序插入(5)实现一个升级版的search函数按顺序查找(6)实现get_count函数得到链表元素个数,28,t课件,综合实例,两个扩展函数:(1)实现一个链表排序函数,使用冒泡排序的方法。(2)遍历一个链表,找到链表的中点节点。(3)寻找某一个节点之前的那个节点,29,t课件,类malloc函数,calloc函数void *calloc( size_t num, size_t size ); relloc函数void *realloc(void *mem_address, unsigned int newsize);,30,t课件,综合实例,实现一个可变的数组,从一个键盘输入若干个数字,以-1结尾。并将其逆序输出。提示:作为数组的缓冲区的大小是固定的,当读取的数字的数目超过数组大小的时候需要使用realloc函数扩展缓冲区数组。,31,t课件,综合实例,实现一个realloc函数,32,t课件,动态内存分配进阶,深入理解动态分配内存的内部机制,33,t课件,堆和栈,代码段,数据段,环境变量和命令行参数,栈,堆,进程地址空间,34,t课件,malloc函数的机制,分配原则最先适合分配方法malloc内部调用sbrk()系统调用一个进程使用一个堆,所有内存由操作系统管理问题:如果申请一个内存并没有释放,当进程结束运行的时候,会造成内存泄露么吗?,35,t课件,malloc函数的实现,内存控制块结构定义:structmem_control_blockintis_available; /* 该块是否可用 */intsize; /* 该块的大小 */;,36,t课件,malloc函数的实现,两个重要的全局变量堆底,分配块的第一块:void*managed_memory_start;堆顶,分配块的最后一块void*last_valid_address;,37,t课件,malloc代码分解,函数的参数:void*malloc(longnumbytes)numbytes是要申请的字节数,但是并不包括内存控制块结构,也就是说我们实际需要的空间是numbytes + sizeof(structmem_control_block),38,t课件,malloc代码分解,几个重要的局部变量:void*current_location; structmem_control_block*current_location_mcb;void*memory_location;,39,t课件,malloc代码分解,重要的语句:numbytes=numbytes+sizeof(structmem_control_block); /* 得到完整的需要空间,用户需要的空间 + 内存控制块结构 */current_location=managed_memory_start; /* 从内存块队列的头开始遍历整个内存队列 */,40,t课件,malloc代码分解,while(current_location!=last_valid_address) current_location_mcb= (structmem_control_block*)current_location; if(current_location_mcb-is_available) if(current_location_mcb-size=numbytes)current_location_mcb-is_available=0; memory_location=current_location;break;current_location=current_location+ current_location_mcb-size;,41,t课件,malloc代码分解,如果现有的内存块不能满足需要:if(!memory_location) sbrk(numbytes);memory_location=last_valid_address;last_valid_address=last_valid_address+numbytes;current_location_mcb=memory_location;current_location_mcb-is_available=0;current_location_mcb-size=numbytes;,42,t课件,malloc代码分解,memory_location=memory_location+sizeof(structmem_control_block); /* 返回给用户可用内存的地址,跳过内存控制块结构 */returnmemory_location; /* 返回 */,43,t课件,sbrk系统调用,malloc代码大部分都由库来完成,为什么还要有这个系统调用?这个系统调用做了什么?为什么只有内存增加的时候需要系统干预?现代操作系统的存储机制,44,t课件,free函数的实现,voidfree(void*firstbyte)structmem_control_block*mcb;mcb=firstbyte-sizeof(structmem_control_block);mcb-is_available=1; /* 这一步是最关键的 */return;,45,t课件,free机制总结,并不是真正的释放,只是将内存块标记为可用。问题1:释放内存后,系统显示的可用内存数会发生改变吗?问题2:释放的内存还可以引用吗?,46,t课件,非常规使用,(1)当申请0个字节时会出现什么情况例如:int *p;p = (int *)malloc(0);(2)释放一个非动态内存申请的空间例如:int array10, *p;p = array; free(p);,47,t课件,两种内存分配的比较,动态分配内存和非动态分配内存的比较,48,t课件,memset函数概念,如果需要将一块内存设置为同一个值的时候,需要使用memset函数。例如:分配一个缓冲区,将该缓冲区内的值清零,49,t课件,memset函数原形,void memset(void *s, int n, size_t size);s:需要设置内存的首地址n:需要被设置的值size:需要设置的字节数,50,t课件,memset函数实例,#include int main()char s10;memset(void *)s, a, 10);s10 = 0;printf(“%sn”, s);return 0; 输出结构为:aaaaaaaaa,51,t课件,综合实例,使用memset函数和malloc函数实现一个calloc函数,52,t课件,memset函数实例,#include int main()char s10;memset(void *)s, a, 10);s10 = 0;printf(“%sn”, s);return 0; 输出结构为:aaaaaaaaa,53,t课件,memcpy函数概念,当需要在两块内存之间进行数据拷贝的时候需要使用memcpy函数其原形为:void * memcpy(void *dest, const void * src, size_t n);dest:复制到目的地址src:复制的源地址n:需要复制的字节数,54,t课件,memcpy函数实例,#include int main()char s = “hello”, d10;memcpy(d, s, 5);d5 = 0;printf(“%s”, d);return 0;运行结果:hello,55,t课件,替代函数,void bzero(void *s, size_t n);void bcopy(void * dest, const void * src, size_t n);,56,t课件,其它内存块操作的函数,memccpy(拷贝内存内容) 定义函数 void * memccpy(void *dest, const void * src, int c,size_t n);函数说明 memccpy()用来拷贝src所指的内存内容前n个字节到dest所指的地址上。与memcpy()不同的是,memccpy()会在复制时检查参数c是否出现,若是则返回dest中值为c的下一个字节地址。返回值为0表示在src所指内存前n个字节中没有值为c的字节。,57,t课件,其它内存块操作的函数,memcmp(比较内存内容) 相关函数 bcmp,定义函数 int memcmp (const void *s1,const void *s2,size_t n);函数说明 memcmp()用来比较s1和s2所指的内存区间前n个字符。字符串大小的比较是以ASCII码表上的顺序来决定,次顺序亦为字符的值。memcmp()首先将s1第一个字符值减去s2第一个字符的值,若差为0则再继续比较下个字符,若差值不为0则将差值返回。例如,字符串Ac和ba比较则会返回字符A(65)和b(98)的差值(33)。返回值 若参数s1和s2所指的内存内容都完全相同则返回0值。s1若大于s2则返回大于0的值。s1若小于s2则返回小于0的值。,58,t课件,其它内存块操作的函数,memmove(拷贝内存内容) 定义函数 void * memmove(void *dest,const void *src,size_t n);函数说明 memmove()与memcpy()一样都是用来拷贝src所指的内存内容前n个字节到dest所指的地址上。不同的是,当src和dest所指的内存区域重叠时,memmove()仍然可以正确的处理,不过执行效率上会比使用memcpy()略慢些。,59,t课件,需要注意的问题,以上函数需要使用的头文件为string.h进行内存块复制的时候要注意目的地址和源地址交叉的问题,60,t课件,动态内存分配基础:1 malloc函数 2 free函数 3 动态内存分配的特点动态内存分配进阶:1 堆和栈的存储布局 2 malloc函数的内部机制 3 malloc函数的实现 4 sbrk()系统调用 5 free函数的内部机制 6 free函数的实现 7 动态内存分配和静态内存分 配的比较 8 类malloc函数,本次课程知识点总结,61,t课件,Thank you,62,t课件,

    注意事项

    本文(C语言动态分配内存课件.ppt)为本站会员(小飞机)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开