C+动态内存分配与引用.ppt

上传人:san****019 文档编号:19954977 上传时间:2021-01-18 格式:PPT 页数:23 大小:1.90MB
返回 下载 相关 举报
C+动态内存分配与引用.ppt_第1页
第1页 / 共23页
C+动态内存分配与引用.ppt_第2页
第2页 / 共23页
C+动态内存分配与引用.ppt_第3页
第3页 / 共23页
点击查看更多>>
资源描述
1 对于计算机程序设计而言,变量和对象在 内 存中的分配 都是编译器在 编译程序时安排 好 的,这带来了极大的不便,如数组必须大开 小用,指针必须指向一个已经存在的变量或 对象。 对于不能确定需要占用多少内存的情况, 动 态内存分配 解决了这个问题。 C/C+定义了 4个内存区间: 代码区 , 全局数 据区 , 栈区 , 堆( heap)区 。 2 通常定义变量时,编译器在编译时根据该变 量的类型,在适当的时候为他们分配所需的 内存空间大小。这种内存分配称为 静态存储 分配 。 但有些操作只有在程序运行时才能确定,这 样编译器在编译时就无法为他们预定存储空 间,只能在程序运行时,系统根据运行时的 要求进行内存分配,这种方法称为 动态存储 分配 。 所有动态存储分配都在堆区中进行 。 3 全局变量 静态数据 常量 函数 函数运行 时分配的 局部变量、 函数参数、 返回数据、 返回地址 等 内存中剩余的 空间由程序员 负责申请和释 放在 C+里堆 空间的申请和 释放分别用到 操作符: new 和 delete 全局数据区 data area 代码区 code area 栈区 stack area 堆区 heap area 4 当程序运行到需要一个动态分配的变量或对 象时 , 必须向系统 申请取得 堆区中的一块所需 大小的存储空间 , 用于存储该变量或对象 。 当不再使用该变量或对象时 , 也就是它的生 命结束时 , 要 显式释放 它所占用的存储空间 , 这样系统就能对该堆空间进行再次分配 , 做到 重复使用有限的资源 。 在 C+中 , 申请和释放堆中分配的存储空间 , 分别使用 new和 delete这两个运算符来完成 , 其 使用的格式如下: 指针变量名 =new 类型名 (初始值 ); delete 指针名 ; new运算符 返回 的是一个指向所分配类型变量 (对象)的 指针 。对所创建的变量或对象,都 是通过该指针来间接操作的,而 动态创建的对 象本身没有标识符名。 6 一般定义变量和对象时要用标识符命名,称 命名对象 ,而动态的称 无名对象 。 new表达式的操作序列如下: 从堆区分配对象, 然后用括号中的值初始化该对象 。从堆区分配 对象时, new表达式调用库操作符 new()。例如: int *pi=new int(0); 说明: pi现在所指向的变量是由库操作符 new()分配的,位于程序的堆区中,并且该 对 象未命名 。 堆 i 下面看演示: 用初始化式 (initializer)来显式初始化 int *pi=new int(0); 当 pi生命周期结束时 , 必须释放 pi所指向的目标: delete pi; 注意这时释放了 pi所指的目标的内存空间,也就是 撤销了该目标,称动态内存释放( dynamic memory deallocation),但 指针 pi本身并没有撤销 ,它自 己仍然存在,该指针所占内存空间并未释放。 使用 new运算符时必须已知数据类型, new运算符会向系 统堆区申请足够的存储空间,如果申请成功,就返回该 内存块的首地址,如果申请不成功,则返回零值。 一般格式 格式 1:指针变量名 =new 类型标识符; 格式 2:指针变量名 =new 类型标识符 ( 初始值 ) ; 格式 3:指针变量名 =new 类型标识符 内存单元个数 ; 说明:格式 1和格式 2都是申请分配某一数据类型所占字节数的 内存空间;但是格式 2在内存分配成功后 , 同时将一初值存 放到该内存单元中;而格式 3可同时分配若干个内存单元 , 相当于形成一个 动态数组 。 9 【 例 9 1:利用 new对变量进行分配空间 】 #include using namespace std; void main() char *pc; int *pi; pc=new char; pi=new int(8); *pc=a; coutpcendl; cout*piendl; /格式 1 /格式 2 输出结果: a 8 a 堆区 8 pc pi 栈区 1000 1001 如果内存分配失败,则 返回零值。所以在动态 分配内存时,应对返回 的指针进行检查 10 /通过指针指向动态分配的内存的首地址 对于数组进行动态分配的格式为: 指针变量名 =new 类型名 下标表达式 ; delete 指向该数组的指针变量名 ; 两式中的 方括号 是非常重要的,两者必须配对使用, 如果 delete语句中少了方括号,因编译器认为该指针 是指向数组第一个元素的指针,会产生 回收不彻底 的 问题( 只回收了第一个元素所占空间 ), 加了方括号 后就转化为指向数组的指针,回收整个数组 。 delete 的方括号中 不需要 填 数组元素数 ,系统自 知。即使写了,编译器也忽略。 请注意 “下标表达式”不是常量表达式 ,即它的值不 必在编译时确定, 可以在运行时确定 。 【 例 9 2: new 运算符为数组分配空间 】 void main() char * string=new char20; char str20; strcpy(string,It is a string.); strcpy(str,It is a string too.); coutstringendl; coutstrendl; 问:内存区域中,栈区怎么变化?堆区怎么变化? 12 I t I t 堆区 栈区 str string 13 【 例 9 3:动态数组的建立与撤销 】 void main() int n; char *pc; cout请输入动态数组的元素个数 n; /在运行时确定,可输入 17 pc=new charn; /申请 17个字符(可装 8个汉字和一个结束符)的内存空间 strcpy(pc,堆内存的动态分配 ); coutpcendl; delete pc; /释放 pc所指向的 n个字符的内存空间 使用 new运算符分配的内存一定要释放,否则 会产生系统内存泄漏。如: void main() char *pc; int *pi; pc=new char; pi=new int(8); *pc=a; coutpcendl; cout*piendl; 15 a 8 pc pi 栈区 1000 1001 当该函数或者该程序执行完毕后系统弹栈, pc和 pi这两个变量将消失,但他们指向的 堆内的内存并不会自动释放,那么该内存 将再不能使用,除非系统重启 堆区 void main() char *pc=NULL; int *pi; pc=new char; pi=new int(8); *pc=a; coutpcendl; cout*piendl; if(pc) delete pc; if(pi) delete pi; 17 void main() char * string=new char20; if (string=0) return; char str20; strcpy(string,It is a string.); strcpy(str,It is a string too.); coutstringendl; coutstrendl; delete string; 对 于 动 态 申 请 数 组 空 间 的 释 放 18 I t I t 堆区 栈区 str string 回收的空间 1000 1000 19 20 【 例 9 4】 从键盘输入 10个 int型数,而后按输入 的相反顺序输出它们。要求使用 new运算符动态 申请数据空间存放数据。 程序执行后的输入输出 界面为 : 输入: 1 2 3 4 5 6 7 8 9 10 运行输出: 10 9 8 7 6 5 4 3 2 1 21 void main() int i, *a, *p; a = new int10; coutinput 10 integers:endl; for(i=0; i*(a+i); /也可用 ai cout- The result -=a; p-) cout*p ; coutendl; 以变量形式分配内存比较死板。有了 new和 delete,就可 以实现一种动态分配内存的形式,即通过指针引用,而 内存的分配和释放可以在程序的任何地方进行。 动态分配失败。 返回一个空指针( NULL), 表示发生了异常,堆资源不足,分配失败。 指针删除与堆空间释放。 删除一个指针 p ( delete p;)实际意思是删除了 p所指的目标 (变量或对象等),释放了它所占的堆空间, 而不是删除本身,释放堆空间后,成了 空 指针 。 内存泄漏( memory leak)和重复释放 。 new与 delete 是配对使用的, delete只能释放堆空间。如 果 new返回的指针值丢失,则所分配的堆空间无法回收, 称内存泄漏,同一空间重复释放也是危险的,因为 该 空间可能已另分配 ,所以必须妥善保存 new返回的指针, 以保证不发生内存泄漏,也必须保证不会重复释放堆 内存空间。 动态分配的变量或对象的生命期。 我们也称堆空 间为自由空间( free store), 但必须记住释放该对 象所占堆空间,并只能释放一次,在函数内建立,而 在函数外释放,往往会出错。
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


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


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

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


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