C语言动态分配内存.ppt_第1页
C语言动态分配内存.ppt_第2页
C语言动态分配内存.ppt_第3页
C语言动态分配内存.ppt_第4页
C语言动态分配内存.ppt_第5页
已阅读5页,还剩58页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

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 仍然可以正确的处理

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论