malloc/free和new/delete的区别和联系:
区别:
malloc/free
- 函数原型
void *malloc(long NumByte);该函数分配了NumBytes个字节,并返回了指向这块内存的指针.如果分配失败,则返回一个空指针(NULL);
void free(void*FirstByte):该函数是将之前malloc分配的空间还给程序或者操作系统,也就是释放了这块内存. - 内存操作:
malloc函数的参数借宿需要分配的内存字节数,如果内存能够满足亲菇凉,那么将返回一个指向这块内存起始位置的地址
free函数释放的是指针指向的空间,而不是释放指针本身,指针必须这下ing实发内存空间的首地址
new/delete
- new/delete 是操作符
操作时发生的事情:
使用new时:
1)内存被分配,通过operator new() (operator new()底层使用malloc实现)
2)为被分配的内存低啊用一个或多个构造函数构建对象使用delete时:
1)为被释放的内存调用一个或多个析构函数;
2)释放内存,通过operaor delete ()函数(operator delete函数底层是用free实现的)
原理图:
new—>operaor new()—->malloc—–>constructor fun—-> return ptr
new[count]—>operaor new[]—->malloc—–>constructor fun(call count次)—-> return ptr- 特殊的是:
在使用delete时,不使用”[]”,delete便假设删除对象时单一对象.否则便假设删除对象是一个数组.
因此,如果在调用new时使用了”[]”,则在调用delete时也使用”[]”,否则有可能导致野指针的问题.
malloc/free 和new/delete的本质区别:
- malloc/free 是c/c++语言的标准库函数,new/delete是c++的运算符
- new可以自动分配空间大小
- 对于用户自定义的对象而言,用malloc/free无法满足动态管理对象的要求.对象在穿啊构建的同时要执行构造函数,对象在消亡之前要自动执行析构函数由于malloc/free是库函数而不是运算符,不在比一起去控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free.因此,c++需要一个能UI对象完成动态内存分配和初始化工作的运算符new,以及一个能对对象完成清理与释放内存干工作的运算符delete
总之,new/delete能进行对对象进行构造和析构函数的调用进而对内存进行更加详细的工作,而malloc/free不能.
联系:
既然new/delete的功能能完全覆盖malloc/free,为什么c++还保留malloc/free呢?
因为c++程序经常需要调用c函数,而c程序只能调用malloc/free管理内存.如果用free释放new创建的动态对象,那么该对象会因无法执行析构函胡而可能导致程序出错.如果用delete释放malloc申请得动态内存,理论上程序不会出错,但是该程序的可读性会非常差.所以new/delete,malloc/free必须配对使用.
实现NEW_ARRY/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);