堆是C++中动态数据区(栈区)、全局和静态数据区和程序代码区外的另一个内存区域。堆区采取链表式管理(链表稍后详细介绍),其容量取决于虚拟内存。
栈区由编译器自动分配和释放,用于存放函数参数和局部变量。
堆区与栈区的区别还有:
- 堆是由低地址向高地址扩展,先申请的在低地址处分配。栈是由高地址向低地址扩展,先申请的在高地址处分配。
- 堆空间容量较大,栈空间较小。
- 堆是不连续的空间,栈是连续的空间。
- 在申请空间后,栈的分配要比堆的快。对于堆,频繁的分配和释放不同大小的堆空间,会产生很多堆内碎块。
- 栈的生命期最短,到函数调用结束时;堆中的生命期是到被用户在程序中释放时(如果整个过程中都未释放,则程序结束时,这部分内存将从系统中丢失,直到计算机重新启动)。
7.9.1 new运算符
new 运算符用于为指针变量动态分配堆内存。new运算符使用格式有三种:
point=new <类型说明符>
point=new <类型说明符> (<初值>)
point=new <类型说明符> [<表达式>]
【例7.33】使用new在堆上申请空间
int *p1=new int; //p1指向new申请的空间
float *p2=new float(3.14);
//p2指向new申请的空间,初始化为3.14
char *p3=new char[20];
//用p3指向在堆上申请的字符数组
int *p4=new int[3*5];
//用p4指向在堆上申请的3行5列的二维数组
int &ref=*new int;//申请堆空间来初始化引用
【例7.35】设计一程序,实现动态内存分配。
void main()
{ int n,*p1,*p2;
float (*p3)[10];
p1=new int[10]; //申请固定大小数组
cout<<”请输入n的值:”;
cin>>n;
p2=new int[n]; //申请动态数组
p3=new float[5][10];//申请动态二维数组
}
【例7.35】设计一程序,实现动态内存分配。
void main()
{ int n,*p1,*p2;
float (*p3)[10];
p1=new int[10]; //申请固定大小数组
cout<<”请输入n的值:”;
cin>>n;
p2=new int[n]; //申请动态数组
p3=new float[5][10];//申请动态二维数组
}
【例7.35】设计一程序,实现动态内存分配。
void main()
{ int n,*p1,*p2;
float (*p3)[10];
p1=new int[10]; //申请固定大小数组
cout<<”请输入n的值:”;
cin>>n;
p2=new int[n]; //申请动态数组
p3=new float[5][10];//申请动态二维数组
}
-
用new运算符申请的堆空间 没有名字,只能 用指针指向其首地址 或 使用引用 。在申请的空间释放以前,该指针不能再指向其它地址,以防内存泄露。
-
当没有足够的堆空间用于分配时,new运算符返回空指针NULL。
7.9.2 delete运算符
delete运算符的功能是用来==释放(删除)==使用new在堆上申请的空间,将申请的空间归还给系统。使用delete有三种格式:
delete <指针名>
delete [ ]<指针名>
delete [<表达式>]<指针名>
【例7.36】释放new申请的堆空间。
int *ptr1;
ptr = new int(5); //ptr指向申请堆空间
delete ptr; //释放指针ptr空间
int &ref=*new int; //将指针转换为引用
delete &ref; //释放引用堆空间时要
//加“&”号
【例7.37】申请一维数组堆空间并释放之。
int *p;
p=new int[10];//p指向申请数组堆空间
delete [ ]p; //释放p指向的数组
关于delete运算符,须注意:
(1) 必须使用由运算符new返回的指针;
(2) 该运算符也适用于空指针;(但实际上并不进行任何操作)
(3) 指针名前只用一对方括号符,并且不管所释放数组的维数。如果释放的是多维数组,方括号内数字表示该数组第1维的大小。