c++动态内存管理

来源:互联网 发布:c 数据采集 编辑:程序博客网 时间:2024/06/05 11:23

一、变量在内存中的存储
这里写图片描述
二、总结并剖析malloc/free、new/delete之间的关系和差异
在c语言中,动态开辟内存空间有malloc/calloc/realloc三种方式,用free进行空间的释放

void Test(){int* p1=(int*)malloc(sizeof(int)* 4);free(p1);int* p2=(int*)calloc(4,sizeof(int));int* p3=(int*)realloc(p2,sizepf(int)*6);free(p3);}

realloc可以对空间进行扩容,当p2指针指向的空间后足够开辟所需要的空间大小时,直接开辟空间,不够时,重新开辟一块空间,让p2指向新开空间。
c++中,通过new/delete进行内存管理

void Test(){ int* p=new int[4]; delete p;}

他们都是内存空间的动态开辟与释放,存在以下几点差异:
(1)malloc/free只进行空间的开辟与释放,new/delete还会调构造函数和析构函数对空间进行初始化和清理。
(2)malloc/free需要手动计算类型大小且返回值为void*,new/delete会自己计算类型大小,返回对应类型的指针。
(3)malloc空间开辟失败返回0,new空间开辟失败抛异常。
三、new/delete,new[]/delete[]到底做了些什么事情
通过调用内部函数可以发现它们的内部实现为:
这里写图片描述
由此可见,operator new/operator delete只是malloc/free的一层封装,new先调operator new进行空间的分配,再调构造函数来初始化对象,delete先调析构函数清理成员,在调operator delete进行空间的释放。
new[N]先调operator new分配空间,再调N次构造函数对对象进行初始化,delete[]调N次析构函数,再调operator delete进行空间的释放。
在分配空间时,会在开始多分配4个字节存放对象的个数N。
这里写图片描述
返回时返回的是p指向的空间的地址,所以释放时应先将p向前取4个字节解引用再释放p.
四、实现NEW_ARRAY/DELETE_ARRAY宏,模拟new[]/delete[]申请和释放数组。

#include <iostream>using namespace std;#define NEW(ptr,type)                                    \do                                                       \{                                                        \    ptr = (type*)operator new(sizeof(type));             \    new(ptr)type;                                        \}while (0)#define DELETE(ptr,type)                                 \do                                                       \{                                                        \    ptr->~type();                                       \    operator delete(ptr);                                \} while (0)#define NEW_ARRAY(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 (0)#define DELETE_ARRAY(ptr,type)                           \do                                                       \{size_t n = *((int*)ptr - 1);                            \for (size_t i = 0; i < n; ++i)                           \{                                                        \    (ptr + i)->~type();                                  \}                                                        \    operator delete((type*)((int*)ptr-1));               \}while (0)class AA{public:    AA()    {        cout << "AA()" << endl;    }    ~AA()    {        cout << "~AA()" << endl;    }};int main(){    AA* p1=NULL;    NEW(p1, AA);    DELETE(p1, AA);    //free(p1);    NEW_ARRAY(p1, AA, 10);    DELETE_ARRAY(p1, AA);    system("pause");    return 0;}
原创粉丝点击