一、new / delete 和 malloc / free
C语言提供了malloc 和 free两个系统函数完成对堆内存的申请和释放,而C++提供了两个关键字new 和 delete。
1、使用规则
- new/delete是关键字,效率高于malloc和free。
- 配对使用,避免内存泄漏和多重释放。避
- 免交叉使用,比如malloc申请空间delete释放,new出的空间被free。
- new/delete 主要是用在类对象的申请和释放。申请的时候会调用构造器完成初始化,释放的时候,会调用析构器完成内存清理。
2、new的用法示例
//开辟单地址空间
int *p = new int; //开辟大小为sizeof(int)空间
int *q = new int(5); //开辟大小为sizeof(int)的空间,并初始化为5。
//开辟数组空间
//一维
int *a = new int[100]{0};//开辟大小为100的整型数组空间,并初始化为0。
//二维
int (*a)[6] = new int[5][6];
3、delete的用法示例
//释放单个int空间
int *a = new int;
delete a;
//释放int数组空间
int *b = new int[5];
delete []b;
4、new / delete 和 malloc / free 区别
- malloc 和 free 是库函数,而new和 delete是C++操作符;
- new需要自己计算空间大小,比如:
int *a = new int;
malloc需要指定大小,比如:
int *a = (int *) malloc (sizeof(int));
- new在动态分配内存的时候可以初始化对象,调用其构造函数,delete在释放内存时候调用对象的析构函数。而malloc只分配一段给定的大小内存,并返回该内存首地址指针,如果失败返回NULL;
- operator new / operator delete可以重载,而malloc不行;
- new可以调用malloc来是实现。而malloc不能调用new来实现;
- 对于数据,C++定义new[] 专门进行动态数组分配,用delete[] 进行销毁。new[] 会一次分配内存,然后多次调用构造函数,delete[] 会先多次调用析构函数,然后一次性释放。
char * pa = new char[100];
char * pb = (char*)malloc(sizeof(char)*100);
- malloc能够直观地重新分配内存,使用malloc分配内存后,如果在使用过程中发现内存不足,可以使用realloc函数进行内存重新分配实现内存的扩充。
5、new 和 malloc 内部实现的区别
new可以理解为两步:
- 调用 operator new() 分配内存,如果内存不足分配失败,抛出异常;
- 如果需要的话,在分配的内存上初始化(赋值或者调用构造)。
int *a = (int *)malloc ( sizeof (int ));
if(NULL == a)
{
...
}
else
{
...
}
从C语言走入C++阵营的新手可能会把这个习惯带入C++:
int * a = new int();
if(NULL == a)
{
...
}
else
{
...
}
实际上这样做一点意义也没有,因为new根本不会返回NULL,而且程序能够执行到if语句已经说明内存分配成功了,如果失败早就抛异常了,后面的代码就不会执行了。正确的做法应该是使用异常机制:
try
{
int *a = new int();
}
catch (std::bad_alloc& e)
{
...
}