1.C语言动态内存管理
在C语言中,我们主要对内存的动态管理主要使用的是malloc和free两个C标准库函数,所以我们主要来介绍一下malloc/free
malloc
malloc函数原型
void* __cdecl malloc(size_t _Size);malloc 不保证成功 要检测return
malloc首先会扫描之前由free()所释放的空闲内存块列表,以求找到尺寸大于或等于要求的一块空闲内存。如果这一内存块的尺寸正好与要求相当,就将它返回给调用者,如果是一块较大的内存,那么将对其进行分割,在将一块大小相当的内存返回给调用者的同时,把较小的那块空闲内存块保留在空闲列表中。
malloc需要分配的内存会比实际的size多36byte
mallco如果分配失败,则返回一个空指针(NULL)
当不需要再使用申请的内存时,记得释放
malloc不会调用构造函数函数
free
free是将之前用malloc分配的空间还给程序或者是操作系统
free不会调用析构函数
不能free所申请空间的一部分
所申请的空间只能free一次,如果free两次以上会出错。(释放空指针例外,释放空指针其实也等于啥也没做,所以释放空指针释放多少次都没有问题)
free()释放的是指针指向的内存!注意!释放的是内存,不是指针!指针并没有被释放,指针仍然指向原来的存储空间。
2.在C++中使用C库函数申请内存什么情况下会出问题?
在使用malloc对一个含有析构函数的类申请空间,且用delete[]来释放是,程序会出现崩溃
在使用new[]对一个含有析构函数的类申请空间是,用free释放,程序会出现崩溃
3. C++是如何进行动态内存申请的?
C语言内存管理方式在C++中可以继续使用,同时C++又提出了自己的内存管理方式:C++中通过new和delete运算符进行动态内存管理。
在使用关键字new后会先申请空间,在调用构造函数,在使用delete时,会先调用构造函数,在释放空间。
而关键字new delete在底层会调用自己的重定义函数operator new() 和 operator delete(),而在重定义new和delete中,还是会调用malloc和free,因此new和delete是对malloc和free的封装,并且在一定程度上比malloc和free安全。
因此,一般情况下使用 new 和 delete进行内存申请。
4. 剖析new、delete、new[]、delete[]的原理
new
new是一个关键字
new不会出错,不需要检验返回值,即不需要判空
new在底层调用了 void* operator new(size_t size),而operator在底层有调用了malloc,原型如下:
void* operator new(size_t nSize) { return malloc(nSize); }整个调用过程为:
new->计算字节数->operator new(字节数)->malloc(字节数)->构造函数new会自动计算字节数
new先申请空间,在调用构造函数。
delete
delete是一个关键字
delete在底层调用了operator delete(), operator delete()调用了free,原型如下:
void operator delete(void* p) { free(p); }delete的整个调用过程如下
delete->调用析构函数,清理对象中的资源->dperator delete(p)->free(p)delete会自动调用析构函数
delete先调用析构函数,在释放空间
new[]
new[]在底层调用了 operator new[];
new[]整体的调用过程如下:(test为一个类)
new test[N]->operator new[](sizeof(test)*N + 4)->operator new(size)->malloc(size)->用N次构造函数new[]会比new多申请4个字节的空间,用来存放申请空间的个数N
将对象个数填写到空间的前4个字节后,将空间的首地址向后偏移4个字节
同样的new[],会自动的计算空间大小
delete[]
但存在析构函数时,new[] 会对申请4个字节,且向后偏移4个字节,delete[]会向前偏移4个字节
因此使用delete或者free会崩溃(不会向前偏移,只释放部分空间)
5. new/delete、new[]/delete[]、 malloc/free之间的区别
new/delete 和 malloc/free之间的区别
new能够自动计算需要分配的内存空间,而malloc需要手工计算字节数。例如,int* p1=new int[2] , int* p2=malloc(2*sizeof(int))。
new/delete直接带具体类型的指针,malloc/free返回void类型的指针。
new是类型安全的,而malloc不是。例如,int* p=new float[2],编译时就会报错;而int* p=malloc(2*sizeof(float)),编译时编译器就无法指出错误来。
new一般由两步构成,分别是new操作和构造。new操作对应于malloc,但new操作可以重载,可以自定义内存分配策略,不做内存分配,甚至分配到费内存设备上,而malloc不可以。
new将调用构造函数,而malloc不能;delete将调用析构函数,而free不能。
malloc/free需要库文件stdlib.h支持,new/delete则不需要库文件支持。
new[]/delete[] 和 new/delete的区别
类存在显示析构函数时,会多开辟4个字节的空间
new[] 对多次调用构造函数。
delete会多次调用析构函数
本文详细探讨了C++中的动态内存管理,包括C语言中的malloc/free,C++中的new/delete、new[]/delete[],以及它们与malloc/free的区别。特别强调了new/delete在调用构造和析构函数方面的特性,以及new[]在处理类对象数组时的额外步骤。
2万+

被折叠的 条评论
为什么被折叠?



