C语言提供了malloc和free两个系统函数,完成对堆内存的申请和释放。而C++则提供了两个关键字new和delete;
new/delete是关键字,效率高于malloc和free。
配对使用,避免内存泄漏和多重释放。
避免交叉使用,比如malloc申请空间delete释放,new出的空间被free。
new/delete 主要是用在类对象的申请和释放。申请的时候会调用构造器完成初始化,释放的时候,会调用析构器完成内存清理。
new/new[]/delete/delete[] 用法
//开辟单地址空间
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];
//三维
int (*a)[5][6] = new int[3][5][6];
//四维及以上以此类推
//释放单个int空间
int *a = new int;
delete a;
//释放int数组空间
int *b = new int[5];
delete []b;
二维数组
void TestFunc_pointer(unsigned int height, unsigned int width)
{
unsigned int i, j;
// 数组的元素类型为‘int *’,可赋值给指向‘int *’的指针.
int **array2D = new int *[height];
for(i=0; i<height; ++i)
{
array2D[i] = new int[width];
}
// 访问.
for(i=0; i<height; ++i)
{
for(j=0; j<width; ++j)
{
// 内存非连续,注意防止越界.
array2D[i][j] = i * width + j;
}
}
// 首先回收低一级的动态数组.
for(i=0; i<height; ++i)
{
delete[] array2D[i];
}
// 然后回收高一级的动态数组.
delete[] array2D;
}
malloc/free用法
#include <stdlib.h>
type *p;
if(NULL == (p = (type*)malloc(sizeof(type))))
/*请使用if来判断,这是有必要的*/
{
perror("error...");
exit(1);
}
.../*其它代码*/
free(p);
p = NULL;/*请加上这句*/
int *p = (int*)malloc(sizeof(int) * 100);
//分配可以放得下100个整数的内存空间。
二维数组
#include<stdio.h>
#include<stdlib.h>
int main()
{
int **a; //用二级指针动态申请二维数组
int i,j;
int m,n;
printf("请输入行数\n");
scanf("%d",&m);
printf("请输入列数\n");
scanf("%d",&n);
a=(int**)malloc(sizeof(int*)*m);
for(i=0;i<m;i++)
a[i]=(int*)malloc(sizeof(int)*n);
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
printf("%p\n",&a[i][j]); //输出每个元素地址,每行的列与列之间的地址时连续的,行与行之间的地址不连续
}
}
for(i=0;i<m;i++)
free(a[i]);
free(a);
return 0;
}
new和malloc的区别
1 属性
new和delete是C++关键字,需要编译器支持;malloc和free是库函数,需要头文件支持。#include <stdlib.h>
2 参数
使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算。而malloc则需要显式地指出所需内存的尺寸。
int *b = new int[5];
delete []b;
int *p = (int*)malloc(sizeof(int) * 100); //分配可以放得下100个整数的内存空间。
free(p);
3 返回类型
new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故new是符合类型安全性的操作符。而malloc内存分配成功则是返回void * ,需要通过强制类型转换将void*指针转换成我们需要的类型。
4 重载
C++允许重载new/delete操作符,malloc不允许重载。
以成员函数的形式重载 new 运算符:
void * className::operator new( size_t size ){
//TODO:
}
void className::operator delete( void *ptr){
//TODO:
}
以全局函数的形式重载 new 运算符:
void * operator new( size_t size ){
//TODO:
}
void operator delete( void *ptr){
//TODO:
}
两种重载形式的返回值相同,都是void *
类型,并且都有一个参数,为size_t
类型。在重载 new 或 new[] 时,无论是作为成员函数还是作为全局函数,它的第一个参数必须是 size_t 类型。size_t 表示的是要分配空间的大小,对于 new[] 的重载函数而言,size_t 则表示所需要分配的所有空间的总和。
5 内存区域
new做两件事:分配内存和调用类的构造函数,delete是:调用类的析构函数和释放内存。而malloc和free只是分配和释放内存。
new操作符从自由存储区(free store)上为对象动态分配内存空间,而malloc函数从堆上动态分配内存。自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区。而堆是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配,C语言使用malloc从堆上分配内存,使用free释放已分配的对应内存。自由存储区不等于堆,如上所述,布局new就可以不位于堆中。
6 分配失败
new内存分配失败时,会抛出bac_alloc异常。malloc分配内存失败时返回NULL。
7 内存泄漏
内存泄漏对于new和malloc都能检测出来,而new可以指明是哪个文件的哪一行,malloc确不可以。