C语言中使用malloc/calloc/realloc用来在堆上分配空间,free将申请的空间释放掉。
malloc:
原型:extern void *malloc(unsigned int num_bytes)。
功能:分配长度为num_bytes字节的内存块。
1 int *p=(int*)malloc(sizeof(int)); 2 free(p); 3 p=NULL
calloc:
原型:extern void *calloc(int num_elems, int elem_size);
用法:#include <alloc.h>
功能:为具有num_elems个长度为elem_size元素的数组分配内存
1 int *p=(int*)calloc(100,sizeof(int)); 2 free(p); 3 p=NULL;
realloc:
原型:extern void *realloc(void *mem_address, unsigned int newsize);
用法:#include <alloc.h>
功能:改变mem_address所指内存区域的大小为newsize长度。
1 int *p=(int*)malloc(sizeof(int)); 2 realloc(p,10*sizeof(int)); 3 free(p);
问题:为什么分配了空间之后,必须要用户手动去free掉呢?
答案:因为malloc/calloc/realloc都是在堆上分配的,堆上分配的空间必须由用户自己来管理,如果不释放,就会造成内存泄漏。而栈上分配的空间是由编译器来管理的,具有函数作用域,出了函数作用域后系统会自动回收,不由用户管理,所以不用用户显式释放空间。
C++中是通过new和delete操作符进行动态内存管理的。因为new和delete是操作符,所以可以重载。
用一张图说明new和delete的含义:
new和delete以及malloc和free一样,要成对使用。
这是string *s = new string("a value"); 这句表达式内部的实现:
可以得出:
(初始化一个对象时)new内部的调用顺序:new —— operator new —— malloc —— 构造函数 (先申请空间,再调用构造函数)
(初始化若干个对象时)new内部的调用顺序:new —— operator new [ ] —— operator new —— malloc —— 构造函数
(delete单个对象时)delete对象时,调用顺序为:delete —— 析构函数 —— operator delete —— free (先调用析构函数,再释放空间)
(delete多个对象时)delete对象时,调用顺序为:delete [ ] —— 析构函数 —— operator delete —— free
问题:new和delete与malloc和free都是存在堆上的,二者有什么差别?
答案:
1. 它们都是动态管理内存的入口。
2. malloc/free是C/C++标准库的函数,new/delete是C++操作符。
3. malloc/free只是动态分配内存空间/释放空间。而new/delete除了分配空间还会调用构造析构函数进行初始化与清理(清理成员)。
4. malloc/free需要手动计算类型大小且返回值为void*,new/delete可自己计算类型的大小对应类型的指针。
5.new/delete的底层调用了malloc/free。
6.malloc/free申请空间后得判空,new/delete则不需要。
7.new直接跟类型,malloc跟字节数个数。