1:总结并剖析malloc/free和new/delete之间关系和差异。
mallloc和free分别用于执行动态内存的分配和释放
void *malloc(size_t,size);
void free(void pointer);
malloc分配的是一块连续的空间,如果操作系统无法向malloc提供更多的内存空间,malloc就返回一个NULL,malloc的返回值是void*,free的参数必须要么是NULL,要么是malloc realloc,或calloc的返回值.
callloc和reallc
calloc与malloc区别在于calloc在返回指向内存的指针之前把它初始化为0。
void *calloc(size_t num_elements,size_t element_size)
void realloc(void *ptr,size_t new size)
realloc用于修改原先已经分配的内存块的大小,如果原先内存块无法改变大小,realloc将分配一块正确大小的内存,并把原先那块内存上的内容复制到新的快上因此在使用realloc后就不能在使用指向旧内存的指针而应该用realloc所返回的新指针。
如果realloc的第一个参数是NULL,它的内存等同malloc;
int* p3 = (int*) realloc(p2 , sizeof( int)*6);
这里p2不需要释放
·常见动态内存错误
(1)对NULL指针进行解引用操作(2)对分配的内存操作时越过边界 ,释放并非动态分配的内存(3)试图释放一块动态分配的内存的一部分,以及一块动态内存被释放之后继续被使用
C++通过new和delete动态管理内存。
void Test ()
{
int* p4 = new int; // 动态分配4个字节(1个 int)的空间单个数据
int* p5 = new int(3); // 动态分配4个字节(1个 int)的空间并初始化为3
int* p6 = new int[3] // 动态分配12个字节(3个 int)的空间
delete p4 ;
delete p5;
delete[] p6;
}
!!!一定要注意匹配使用
全局变量、全局静态变量、局部静态变量、局部变量之间的区别是什么?
局部变量与其它三个有本质区别。
局部变量,定义在函数内,作用域为定义位置,到所在大括号结束。 每次执行到定义语句的时候,系统为该变量分配内存,当作用域结束后,内存被释放。
而另外三个,都是在系统运行时就分配内存,在运行过程中都不会释放,直到程序结束。
也就是说,局部变量和其它三个,最明显的区别:
· 生命周期不同
· 分配时间不同
· 分配位置不同。
而另外三个,在这几项上是相同的,之间的区别在于作用域。
全局变量,作用域为整个项目,不管在哪个文件中,只要声明后都可以使用。
静态全局变量,作用域为定义改变量的所在文件。
而静态局部变量,作用域与普通局部变量一样,都是定义位置到所在大括号结束。
·在C++中,申请动态内存与释放动态内存,用new/delete与malloc/free都可以;而且它们的存储方式相同,new/malloc动态申请的内存都位于堆中,无法被操作系统自动回收,需要对应的delete/free来释放空间。此外,对于一般的数据类型,如int、char,它们的效果是一样的。
·malloc/free是C/C++语言的标准库函数,new/delete是C++的运算符。对于类的·对象而言,malloc、free无法满足动态对象的要求。在对象创建的同时要自动执行构造函数,对象消亡之前要自动执行析构函数,而malloc/free不在编译器控制权限之内,无法执行构造函数和析构函数
·new能够自动计算所开辟内存空间的大小,而malloc需要手动计算内存空间的大小
·new/delete直接带具体类型的指针,malloc/free返回void类型的指针。
·new一般由两步构成,分别是new操作和构造。new操作对应于malloc,但new操作可以重载,可以自定义内存分配策略,不做内存分配,甚至分配到费内存设备上,而malloc不可以。
·new将调用构造函数,而malloc不能;delete将调用析构函数,而free不能。
·malloc/free需要库文件stdlib.h支持,new/delete则不需要库文件支持。
2:剖析new/delete、new[]/delete[]到底做了些什么事情。
在使用new的时候做了两件事:
调用operator new分配空间
调用构造函数初始化对象
在使用delete的时候也做了两件事:
调用析构函数清理对象
调用operator delete函数释放空间
在使用new[N]的时候也做了两件事:
调用operator new分配空间
调用N次构造函数初始化N个对象
在使用delete[]的时候也做了两件事:
调用N次析构函数清理N个对象
调用operator delete函数释放空间
3:实现NEW_ARRAY/DELETE_ARRAY宏,模拟new[]/delete[]申请和释放数组。
模拟实现NEW_ARRAY
#define NEW_ARRAY(P, TYPE, N) \
do{ \
int* P_NEW = (int*)malloc(sizeof(TYPE)*N + 4); \
((int*)P_NEW)[0] = N; \
P = (TYPE*)(P_NEW + 1); \
int I_NEW = 0; \
for (; I_NEW < N; I_NEW++) \
new(P + I_NEW)TYPE; \
} while (false);
模拟实现DELETE_ARRAY
#define DELETE_ARRAY(P, TYPE) \
do{\
int n = *((int*)P - 1); \
while (n--)\
(P[n]).~TYPE(); \
free((int*)P - 1); \
} while (false);
模拟实现new[]
#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;
模拟实现delete[]
#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);