您的位置:首页 > 其它

1:总结并剖析malloc/free和new/delete之间关系和差异。 2:剖析new/delete、new[]/delete[]到底做了些什么事情。 3:实现NEW_ARRAY/DE

2017-07-17 23:06 726 查看

1:总结并剖析malloc/free和new/delete之间关系和差异。

2:剖析new/delete、new[]/delete[]到底做了些什么事情。

3:实现NEW_ARRAY/DELETE_ARRAY宏,模拟new[]/delete[]申请和释放数组。

malloc/free和new/delete之间关系和差异

首先先介绍一下malloc/free函数和new/delete操作符:

malloc/freenew/delete:

一.差异

(1)void *malloc(long NumBytes):该函数分配了NumBytes个字节,并返回了指向这块内存的指针。如果分配失败,则返回一个空指针(NULL)。

void free(void *FirstByte): 该函数是将之前用malloc分配的空间还给程序或者是操作系统,也就是释放了这块内存,让它重新得到自由。

new/delete都是操作符。

(2)new能够自动计算需要分配的内存空间,而malloc需要手工计算字节数。例如,int* p1=new int[2] , int* p2=malloc(2*sizeof(int))。

(3)new/delete直接带具体类型的指针,malloc/free返回void类型的指针,接收指针的时候要强制类型转换。

(4)new是类型安全的,而malloc不是。例如,int* p=new float[2],编译时就会报错;而int* p=malloc(2*sizeof(float)),编译时编译器就无法指出错误来。

(5)new一般由两步构成,分别是new操作和构造。new操作对应于malloc,但new操作可以重载,可以自定义内存分配策略,不做内存分配,甚至分配到费内存设备上,而malloc不可以。

(6)new是分配内存和初始化,因此将调用构造函数,而malloc不能;delete将调用析构函数,而free不能。

(7)malloc/free需要库文件stdlib.h支持,new/delete则不需要库文件支持。

注意

此外,需要注意的是:有内存的申请,就必需要有内存的释放,否则就会出现内存泄露的问题,故new/delete、malloc/free必需配对使用。而且,delete或free被调用后,内存不会立即回收,指针也不会指向空,delete或free仅仅是告诉操作系统,这一块内存被释放了,可以被用做其它用途。由于没有重新对这块内存进行写操作,所以内存中的变量数值并没有发生变化,因此,释放完内存后,应该将指针指向置为NULL,防止出现野指针。

二.剖析

(1)new/delete

new做了两件事:1)调用operator new 分配空间;2)调用构造函数初始化对象.

delete做了两件事:1)调用析构函数清理对象;2)调用operator delete 释放空间.

(2)new[ ]/delete[ ]

new[ ]做了两件事:1)调用operator new分配空间;2)调用N次构造函数分别对每个对象进行初始化.

delete[ ]做了两件事:1)调用N次析构函数分别对每个对象进行清理;2)调用operator delete 释放空间.

特别的:

int* p = new AA[3];

实际上在调用构造函数时(自己定义的类),会在p前面4个字节(一个int)用来存储数组成员个数,用来确定具体构造几次和析构几次。



三.实现NEW_ARRAY/DELETE_ARRAY宏,模拟new[]/delete[]申请和释放数组。

#define NEW_ARRAY(PTR,TYPE,N)      \
do{
PTR = (TYPE*)operator new(sizeof(TYPE)*N + 4); \
(*(int*)PTR) = N;                           \
PTR = (TYPE*)((char*)PTR + 4);                \
for (size_t i = 0; i < N; i++)                \
new(PTR + i)TYPE;                         \
} while (false);
#define DELETE_ARRAY(PTR,TYPE)      \
do{
for (size_t i = 0; i < N; i++)  \
PTR[i].~TYPE();           \
PTR = (TYPE*)((char*)PTR - 4);  \
operator delete(PTR);         \
} while (false);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: