re动态内存分配.ppt
《re动态内存分配.ppt》由会员分享,可在线阅读,更多相关《re动态内存分配.ppt(43页珍藏版)》请在三一办公上搜索。
1、动态内存分配,程序运行时动态内存分配(dynamic memory allocation)先复习概念与方法、堆对象与构造函数 然后进一步讨论拷贝构造函数.,堆内存分配,通常编译器在编译时都可以根据变量(或对象)的类型知道所需内存空间的大小,从而在适当的时候为他们分配确定的存储空间。这种内存分配称为静态存储分配。有些操作对象只有在程序运行时才能确定,系统根据运行时的要求进行内存分配,这种方法称为动态存储分配。,1.堆内存的分配与释放,根据申请动态分配,用后显式释放所空间,使系统能做到重复使用有限的资源。,格式如下:指针变量名=new 类型名(初始化式);delete 指针变量名;new运算符返回
2、的是一个指向所分配类型变量(对象)的指针。对所创建的变量或对象,都是通过该指针来间接操作的,而动态创建的对象本身没有名字。,堆区不会自动在分配时做初始化(包括清零),所以必须用初始化操作(initializer)来显式初始化。,从堆区分配对象时,new表达式调用库操作符new()。例如:int*pi=new int(0);/对象未命名它与下列代码序列大体等价:int what=0;int*pi=,0,pi,堆,i,演示:用初始化式(initializer)来显式初始化 int*pi=new int(0);当pi生命周期结束时,必须释放pi所指向的目标:delete pi;注意这时释放了pi所指
3、的目标的内存空间,也就是撤销了该目标,称动态内存释放(dynamic memory deallocation),但指针pi本身并没有撤销,该指针所占内存空间并未释放。,对于数组进行动态分配的格式为:指针变量名=new 类型名下标表达式;释放:Delete 指向该数组的指针变量名;,如果delete语句中少了方括号,因编译器认为该指针是指向数组第一个元素的指针,会产生回收不彻底的问题(只回收了第一个元素所占空间),加了方括号后就转化为指向数组的指针,回收整个数组。,#include void main()int n;char*pc;coutn;/在运行时确定,可输入17pc=new charn;
4、strcpy(pc,堆内存的动态分配);coutpcendl;delete pc;/释放pc所指向的n个字符的内存空间return;,【例1】动态一维数组的建立与撤销,动态分配数组有三个特点:,1.变量n在编译时没有确定的值,而是在运行中输入,按运行时所需分配堆空间,这一点是动态分配的优点,可克服数组“大开小用”的弊端。delete pc是将n个字符的空间释放,而用delete pc则只释放了一个字符的空间;,2.如果有一个char*pc1,令pc1=p,同样可用delete pc1来释放该空间。尽管C+不对数组作边界检查,但在堆空间分配时,对数组分配空间大小是纪录在案的。,3.没有初始化式,
5、不可对数组初始化。,两种方法:动态创建二维数组,double*data,*score;/方法1:score=new doublemn;/方法2:data=new double*m;for(int j=0;jm;j+)dataj=new doublen;,两种方法:释放二维数组,/方法1:delete score;/方法2:for(int i=0;im;i+)delete datai;delete data;,#includeusing namespace std;const int m=4;/行数const int n=6;/列数void desarray(double(*)6);/函数声明v
6、oid main()double(*score)n;/定义二级指针变量 score=new doublemn;/一次分配全部数组单元 if(score=0)cout Could not allocate.;exit(-1);,【例2】动态创建和删除一个m*n个元素的数组。/方法一:采用指向二维数组的指针,一次分配,for(int i=0;im;i+)/初始化数组元素 for(int j=0;jn;j+)scoreij=i*n+j;for(i=0;im;i+)for(int j=0;jn;j+)coutscoreijt;coutendl;desarray(score);/调用函数撤消数组 ret
7、urn;,/二维数组的撤销与内存释放:void desarray(double(*score)n)delete score;,【例2】动态创建和删除一个m*n个元素的数组。/方法二:采用指针数组,二次分配,const int m=4;/行数const int n=6;/列数/先看二维数组的动态创建:void main()double*data;/定义指针数组,相当于*datam data=new double*m;/设置行指针 if(data)=0)cout Could not allocate.Bye.;exit(-1);for(int j=0;jm;j+)dataj=new doublen
8、;/分配一个一维数组为一行 if(dataj=0)cout Could not allocate.Bye.;exit(-1);,for(int i=0;im;i+)for(int j=0;jn;j+)dataij=i*n+j;/初始化数组元素 print(data);/调用函数输出数据 destroy(data);/调用函数进行撤销与内存释放 return;/再看二维数组的撤销与内存释放:void destroy(double*data)for(int i=0;im;i+)delete datai;delete data;/注意撤销次序,与设置相反,指针使用的几个问题:1.动态分配失败。返回一
9、个空指针(NULL),表示发生了异常,堆资源不足,分配失败。,2.指针删除与堆空间释放。删除一个指针p(delete p;)实际意思是删除了p所指的目标(变量或对象等),释放了它所占的堆空间,而不是删除本身,释放堆空间后,成了空悬指针。,内存泄漏(memory leak)和重复释放。new与delete 是配对使用的,delete只能释放堆空间。如果new返回的指针值丢失,则所分配的堆空间无法回收,称内存泄漏,同一空间重复释放也是危险的,因为该空间可能已另分配,所以必须妥善保存new返回的指针,以保证不发生内存泄漏,也必须保证不会重复释放堆内存空间。,动态分配的变量或对象的生命期。无名对象的生
10、命期并不依赖于建立它的作用域,比如在函数中建立的动态对象在函数返回后仍可使用。我们也称堆空间为自由空间(free store)就是这个原因。但必须记住释放该对象所占堆空间,并只能释放一次,在函数内建立,而在函数外释放是一件很容易失控的事,往往会出错。,2.堆对象与构造函数,/动态创建对象class Point public:Point()X=Y=0;coutDefault Constructor called.n;Point(int xx,int yy)X=xx;Y=yy;cout Constructor called.n;Point()coutDestructor called.n;int
11、GetX()return X;int GetY()return Y;void Move(int x,int y)X=x;Y=y;private:int X,Y;,int main()coutStep One:endl;Point*Ptr1=new Point;/调用缺省构造函数 delete Ptr1;coutStep Two:endl;Ptr1=new Point(1,2);/调用带参构造函数 delete Ptr1;return 0;,运行结果:Step One:Default Constructor called.Destructor called.Step Two:Constructo
12、r called.Destructor called.,3.堆对象数组与构造函数,通过new建立的对象要调用构造函数,通过deletee删除对象也要调用析构函数。CGoods*pc;pc=new CGoods;/分配堆空间,并构造一个无名的CGoods对象;.delete pc;/先析构,然后将内存空间返回给堆;,堆对象的生命期并不依赖于建立它的作用域,所以除非程序结束,堆对象(无名对象)的生命期不会到期,并且需要显式地用delete语句析构堆对象,上面的堆对象在执行delete语句时,C+自动调用其析构函数。,class CGoods char Name21;int Amount;float



- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- re 动态 内存 分配

链接地址:https://www.31ppt.com/p-6517499.html