本文将总结C++中的new和delete关键字,及其在动态内存分配的情形。
1、问题引出
对于常见的数组或一个数值变量,在C++中,他们都被存放于“栈区”。由于“栈区”的内存是系统自动分配的,在声明一个数组时,需要事先告诉数组的大小,申请以后,数组大小就固定了。这样,就给我们带来了很多不便,比如大数组只存放了少量的数据。
new关键字就很好的解决了这个问题。由于new申请的内存是在“堆区”,可以有程序员自己申请所需要的大小,而且是动态的。delete关键字是将new申请的内存释放,与new结合使用。若忘记了释放new申请的内存,往往会带来内存泄露的问题。
2、new和delete的应用场景
一般来说,new可以用于动态变量的声明及定义、一维数组的声明及定义以及多维数组的声明及定义。delete与之对应。
2.1 对于动态变量的应用
观察下面的C++代码,代码运行结果及分析在注释中给出
#include<iostream>
using namespace std;
int main()
{
int *a=new int(5); //在堆中申请一个存放整型数据的内存空间,并将地址返回给指针a,将内存空间赋值为5
int *b=new int; //在堆中申请一个存放整型数据的内存空间,并将地址返回给指针b
*b=5; //将指针b的指向的内存空间赋值为5
cout<<"指针a指向的内存空间大小为: "<<sizeof(a)<<endl; //输出int型变量所占空间大小 4
cout<<"指针a指向的整数空间值为: "<<*a<<endl; //输出5
cout<<"指针b指向的整数空间值为: "<<*b<<endl; //输出5
delete b;
delete a;
cout<<"指针a指向的内存空间大小为: "<<sizeof(a)<<endl; //输出int型变量所占空间大小 4
cout<<"指针a指向的整数空间值为: "<<*a<<endl; //报错
//出现上述现象的原因是:delete释放的是指针指向的整数空间(整数变量值),
//再次试图访问该空间时就访问不到了,
//而不会删除指针本身
return 0;
}
2.2 对一维数组和多维数组的应用
观察下面的C++代码,代码运行结果及分析在注释中给出。
仅以二维数组为例,多维数组的操作与二维数组的操作相似。
#include<iostream>
using namespace std;
int main()
{
/*---------------------------------------------一维数组---------------------------------------------------*/
int *a=new int[10]; //在堆中申请一个大小为10的整型内存空间,并返回该空间的首地址
cout<<"a所占内存字节数: "<<sizeof(a)<<endl; //输出4,空间的首地址为一个int类型的指针变量占4个字节
delete []a; //释放申请的整块内存空间
delete a; //仅仅释放了指针a指向的首块空间,没有完全释放申请的空间,将导致未释放空间以后不可申请,造成内存泄露
/*---------------------------------------------二维数组---------------------------------------------------*/
int n=5,m=10;
int **b=new int*[n]; //申请一块具有n=5行的二维数组空间
for(int i=0;i<n;i++)
b[i]=new int[m]; //对于数组的每一行,申请m=10个整型空间
//经过上述操作,已经申请好了一个nxm的二维数组空间
for(int i=0;i<n;i++) //先释放每一行申请的内存空间
delete[]b[i];
delete []b; //再释放行值申请的内存空间
return 0;
}