C/C++动态内存管理

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)用来存储数组成员个数,用来确定具体构造几次和析构几次。
Alt text

三.实现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);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值