point of division
1:总结并剖析malloc/free和new/delete之间关系和差异。
2:剖析new/delete、new[]/delete[]到底做了些什么事情。
3:实现NEW_ARRAY/DELETE_ARRAY宏,模拟new[]/delete[]申请和释放数组。
1. malloc/free和new/delete之间关系和差异
首先,分别介绍一下:
malloc/free:
1、函数原型及说明:
void *malloc(long NumBytes):该函数分配了NumBytes个字节,并返回了指向这块内存的指针。如果分配失败,则返回一个空指针(NULL)。
void free(void *FirstByte): 该函数是将之前用malloc分配的空间还给程序或者是操作系统,也就是释放了这块内存,让它重新得到自由。
2.内存操作:
malloc函数的参数是接受需要分配的内存字节数,如果内存能够满足请求量,那么将会返回:指向被分配的内存块起始位置
free函数释放的是指针指向的内存(不是释放的指针本身,不会删除指针本身),其中指针必须指向所释放内存空间的首地址
由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。
1. 都必须配对使用,这里的配对使用,可不能理解为一个new/malloc就对应一个delete/free,而是指在作用域内,new/malloc所申请的内存,必须被有效释放,否则将会导致内存泄露。
2. 都是申请内存,释放内存,free和delete可以释放NULL指针。
2.剖析new/delete、new[]/delete[]到底所做了什么
new/delete
在使用new的时候做了两件事:
1、调用operator new分配空间
2、调用构造函数初始化对象
在使用delete的时候也做了两件事:
1、调用析构函数清理对象
2、调用operator delete函数释放空间
new[]/delete[]
在使用new[N]的时候也做了两件事:
1、调用operator new分配空间
2、调用N次构造函数初始化N个对象
在使用delete[]的时候也做了两件事:
1、调用N次析构函数清理N个对象
2、调用operator delete函数释放空间
3.实现NEW_ARRAY/DELETE_ARRAY宏,模拟new[]/delete[]申请和释放数组。
#define NEWARRAY(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 DELETEARRAY(PTR, TYPE) \
do \
{ \
size_t N = *((int*)PTR - 1); \
for (size_t i = 0; i < N; ++i)\
PTR[i].~TYPE(); \
PTR = (TYPE*)((char*)PTR - 4);\
operator delete(PTR); \
} while (false); \