C语言动态分配内存.ppt

上传人:sh****n 文档编号:7456703 上传时间:2020-03-21 格式:PPT 页数:62 大小:2.87MB
返回 下载 相关 举报
C语言动态分配内存.ppt_第1页
第1页 / 共62页
C语言动态分配内存.ppt_第2页
第2页 / 共62页
C语言动态分配内存.ppt_第3页
第3页 / 共62页
点击查看更多>>
资源描述
1动态内存分配基础2动态内存分配实例3动态内存分配进阶 C语言动态分配内存 动态分配内存基础 动态分配内存概述 什么时候需要动态分配内存 实例 顺序对一批文件进行解析 但是不知道文件的大小 如何建立缓冲区 malloc函数 malloc函数原型 void malloc size tn n是要分配的内存的大小 返回值是分配内存的块的首地址 malloc函数 例1 使用malloc函数分配一个可以容纳10个整型元素的内存空间 并将其用作一个整型数组 malloc函数 关键代码 int array array int malloc 10 sizeof int 注意 内存大小不能写成数组元素的个数 malloc函数 例2 定义一个结构structtest inta charb intc 10 使用malloc函数分配一个此种结构类型的对象 malloc函数 关键代码 structtest p p structtest malloc sizeof structtest 需要注意的问题 1 malloc函数是一个库函数 它并不是C语言中的关键字 需要头文件才可以使用该函数并不是所有的平台都可以使用该函数 尤其是一些单片机系统 需要注意的问题 2 指针类型转换是必须的 关系到接收分配好的内存块的地址可以向前看多少字节 如果不做指针类型转换会怎么样 void 指针存在的意义 需要注意的问题 3 内存块大小的可移植性问题分配一个整型变量数组应使用 数组元素个数 sizeof int 确定内存块的大小问题 sizeof和strlen函数的区别 free函数 free函数原型 voidfree void p p是要释放的已分配内存的块的首地址 free函数 释放一块动态分配的内存 例如 int p p int malloc sizeof int free p 需要注意的问题 1 free函数同样是一个库函数 2 free函数的参数必须是一个由动态内存分配方法分配的内存块的首地址 使用malloc函数分配的内存 动态分配内存特点 内存空间大小可以是一个变量 其值在运行时确定内存空间在运行时分配 在程序结束时收回 内存的分配由操作系统参与完成动态分配的内存空间在未释放之前均可以被引用 保证其生命期 链表 链表的概述 structnode intnode 数据域 存储结点的值 structnode next 链表示意图 value1 value2 value3 value4 NULL 处理链表使用的函数 动态申请内存 void malloc size tn 释放动态内存 voidfree void 插入一个结点 structnode p 连接b结点和c结点 删除一个结点 structnode p 摘下的b结点一定要释放掉 动态内存分配实例 动态内存分配实例 设计一个学生链表 其每个结点是一个学生信息的集合 每个结点包含如下信息 学生姓名 学号 C语言成绩三项 初始时拥有3个学生 添加一个学生 使用一个函数实现此操作 再删除一个学生 使用另一个函数实现此操作 并打印该学生的信息 实例关键点分析 结点结构 structinfo charname 10 intid intscore structstd structinfo structstd next 实例关键点分析 main函数 intmain void 初始化学生链表 插入一个学生信息结点 删除一个学生的信息 并且打印 return0 实例关键点分析 intinsert char name intid intscore 分配一个structstd结构对象 将参数赋值到结构对应的成员中 return1 正确完成操作 返回1 实例关键点分析 intremove intid structstd res 根据id找到该学生的信息结点 将该结点从链表上取下 使用res保存该节点 释放该结点所占用的内存 return1 成功操作返回1 综合实例 1 实现print函数对其遍历打印链表 2 实现destroy函数释放每一个链表节点 3 实现search函数查找链表中的元素 4 实现一个升级版的insert将元素按顺序插入 5 实现一个升级版的search函数按顺序查找 6 实现get count函数得到链表元素个数 综合实例 两个扩展函数 1 实现一个链表排序函数 使用冒泡排序的方法 2 遍历一个链表 找到链表的中点节点 3 寻找某一个节点之前的那个节点 类malloc函数 calloc函数void calloc size tnum size tsize relloc函数void realloc void mem address unsignedintnewsize 综合实例 实现一个可变的数组 从一个键盘输入若干个数字 以 1结尾 并将其逆序输出 提示 作为数组的缓冲区的大小是固定的 当读取的数字的数目超过数组大小的时候需要使用realloc函数扩展缓冲区数组 综合实例 实现一个realloc函数 动态内存分配进阶 深入理解动态分配内存的内部机制 堆和栈 代码段 数据段 环境变量和命令行参数 栈 堆 进程地址空间 malloc函数的机制 分配原则 最先适合分配方法malloc内部调用sbrk 系统调用一个进程使用一个堆 所有内存由操作系统管理问题 如果申请一个内存并没有释放 当进程结束运行的时候 会造成内存泄露么吗 malloc函数的实现 内存控制块结构定义 structmem control block intis available 该块是否可用 intsize 该块的大小 malloc函数的实现 两个重要的全局变量堆底 分配块的第一块 void managed memory start 堆顶 分配块的最后一块void last valid address malloc代码分解 函数的参数 void malloc longnumbytes numbytes是要申请的字节数 但是并不包括内存控制块结构 也就是说我们实际需要的空间是numbytes sizeof structmem control block malloc代码分解 几个重要的局部变量 void current location structmem control block current location mcb void memory location malloc代码分解 重要的语句 numbytes numbytes sizeof structmem control block 得到完整的需要空间 用户需要的空间 内存控制块结构 current location managed memory start 从内存块队列的头开始遍历整个内存队列 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 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 malloc代码分解 memory location memory location sizeof structmem control block 返回给用户可用内存的地址 跳过内存控制块结构 returnmemory location 返回 sbrk系统调用 malloc代码大部分都由库来完成 为什么还要有这个系统调用 这个系统调用做了什么 为什么只有内存增加的时候需要系统干预 现代操作系统的存储机制 free函数的实现 voidfree void firstbyte structmem control block mcb mcb firstbyte sizeof structmem control block mcb is available 1 这一步是最关键的 return free机制总结 并不是真正的释放 只是将内存块标记为可用 问题1 释放内存后 系统显示的可用内存数会发生改变吗 问题2 释放的内存还可以引用吗 非常规使用 1 当申请0个字节时会出现什么情况例如 int p p int malloc 0 2 释放一个非动态内存申请的空间例如 intarray 10 p p array free p 两种内存分配的比较 动态分配内存和非动态分配内存的比较 memset函数概念 如果需要将一块内存设置为同一个值的时候 需要使用memset函数 例如 分配一个缓冲区 将该缓冲区内的值清零 memset函数原形 voidmemset void s intn size tsize s 需要设置内存的首地址n 需要被设置的值size 需要设置的字节数 memset函数实例 includeintmain chars 10 memset void s a 10 s 10 0 printf s n s return0 输出结构为 aaaaaaaaa 综合实例 使用memset函数和malloc函数实现一个calloc函数 memset函数实例 includeintmain chars 10 memset void s a 10 s 10 0 printf s n s return0 输出结构为 aaaaaaaaa memcpy函数概念 当需要在两块内存之间进行数据拷贝的时候需要使用memcpy函数其原形为 void memcpy void dest constvoid src size tn dest 复制到目的地址src 复制的源地址n 需要复制的字节数 memcpy函数实例 includeintmain chars hello d 10 memcpy d s 5 d 5 0 printf s d return0 运行结果 hello 替代函数 voidbzero void s size tn voidbcopy void dest constvoid src size tn 其它内存块操作的函数 memccpy 拷贝内存内容 定义函数void memccpy void dest constvoid src intc size tn 函数说明memccpy 用来拷贝src所指的内存内容前n个字节到dest所指的地址上 与memcpy 不同的是 memccpy 会在复制时检查参数c是否出现 若是则返回dest中值为c的下一个字节地址 返回值为0表示在src所指内存前n个字节中没有值为c的字节 其它内存块操作的函数 memcmp 比较内存内容 相关函数bcmp 定义函数intmemcmp constvoid s1 constvoid s2 size tn 函数说明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的值 其它内存块操作的函数 memmove 拷贝内存内容 定义函数void memmove void dest constvoid src size tn 函数说明memmove 与memcpy 一样都是用来拷贝src所指的内存内容前n个字节到dest所指的地址上 不同的是 当src和dest所指的内存区域重叠时 memmove 仍然可以正确的处理 不过执行效率上会比使用memcpy 略慢些 需要注意的问题 以上函数需要使用的头文件为string h进行内存块复制的时候要注意目的地址和源地址交叉的问题 动态内存分配基础 1malloc函数2free函数3动态内存分配的特点动态内存分配进阶 1堆和栈的存储布局2malloc函数的内部机制3malloc函数的实现4sbrk 系统调用5free函数的内部机制6free函数的实现7动态内存分配和静态内存分配的比较8类malloc函数 本次课程知识点总结 Thankyou
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!