仿织梦小说网站源码,购物网站排行榜前十名,服装店网站建设规划书,旅游电子商务网站的建设方式内存管理#xff08;1#xff09; 1、各类型数据在内存中的存储空间2、C内存管理方式2.1 针对于内置类型分析2.2 针对于自定义类型分析2.3 C语言与C在申请动态内存失败时的区别 3、operator new 和 operator delete函数#xff08;重点#xff09;3.1 底层知识解析3.2 实现… 内存管理1 1、各类型数据在内存中的存储空间2、C内存管理方式2.1 针对于内置类型分析2.2 针对于自定义类型分析2.3 C语言与C在申请动态内存失败时的区别 3、operator new 和 operator delete函数重点3.1 底层知识解析3.2 实现专属operator new 与 operator delete (了解) 1、各类型数据在内存中的存储空间
int globalVar 1;
static int staticGlobalVar 1;void Test()
{static int staticVar 1;int localVar 1;int num1[10] {1,2,3,4};char char2[] abcd; //常量数据需要在外面加 const char* pChar3 abcd;int* ptr1 (int*)malloc(sizeof(int)*4);int* ptr2 (int*)calloc(4,sizeof(int));int* ptr3 (int*)realloc(ptr2,sizeof(int)*4);free(ptr1);free(ptr2);
}//(1) globalVar 数据段 staticGlobalVar 数据段 staticVar 数据段
// localVar 栈区 num1 栈区
// char2数组名\数组首元素地址 栈区 *char2 代码段
// pChar3指针 栈区 *pChar3 代码段
// ptr1指针 栈区 *ptr1 堆区
//2、C内存管理方式
// C语言内存管理方式在C中可以继续使用但有些地方就无能为力而使用起来比较麻烦因此C又提出了自己的内存管理方式通过new和delete
// 操作符进行动态内存管理。2.1 针对于内置类型分析
void Test()
{int* p1 (int*)malloc(sizeof(int));int* p2 new int;//申请具有5个int的数组int* p3 new int[5];//申请1个int的数组并初始化为5int* p4 new int(5);//C11支持new[] 用{}初始化 C98不支持//将申请具有5个int的数组 进行初始化int* p5 new int[5]{1,2,3};free(p1);delete p2;delete[] p3;delete p4;delete[] p5;//针对内置类型new/delete 跟 malloc/free没有本质的区别只有用法的区别。// new/delete 用法简化了。
}int main()
{Test();return 0;
}2.2 针对于自定义类型分析
class A
{
public:A(int a):_a(a){coutA(): this endl;}~A(){cout ~A(): this endl;}private:int _a;
};int main()
{//堆上申请空间A* p1(A*)malloc(sizeof(A));if (0p1){perror(malloc fail);return 0;}//1、堆上申请空间 2、调用构造函数进行初始化A* p2 new A; //调用默认构造函数A* p2 new A(10); //调用非默认构造函数//申请10个A类型对象的空间并进行初始化A* p3 new A[5]{1,2,3,4,5};delete[] p3; //数组里的对象先初始化后析构//释放空间free(p1);//1、调用 析构函数 清理对象中资源 2、释放空间delete p2;//结论: new/delete 是为自定义类型准备的//不仅在堆上申请出来还会调用构造函数和析构函数进行初始化和清理。//注意new/delete new[]/delete[]一定要匹配使用否则可能会出问题。return 0;
}2.3 C语言与C在申请动态内存失败时的区别
int main()
{// malloc失败返回NULLchar* p1 (char*)malloc(1024u * 1024u * 1024u * 2 - 1);printf(%p\n,p1);// new失败不需要检查返回值它失败是抛异常异常:是面向对象语言出错处理的方式try{//char* p2 new char[1024u * 1024u * 1024u*2-1];char* p2 (char*)operator new(1024u * 1024u * 1024u);printf(%p\n, p2);operator delete(p2);}//当申请空间失败时才会进入catch; 若申请空间成功时就会跳过catch;catch (const exception e){cout e.what() endl;}return 0;
}3、operator new 和 operator delete函数重点
3.1 底层知识解析
// new和delete 是用户进行动态内存申请和释放的操作符。operator new 和 operator delete是系统提供的全局函数new在底层调用operator new全局函数来
// 申请空间delete在底层通过operator delete全局函数来释放空间。
//
// operator new全局函数——帮助new开空间——封装调用malloc{ 若malloc失败了符合C new的失败机制失败抛异常}。
// operator delete全局函数——帮助delete释放空间——封装调用free
//
// new的底层分为两部分调用operator new 调用构造函数; 即new Type(自定义类型) -- call operator new【调用malloc(若开辟空间失败会抛异常)】 call Type构造函数
// delete的底层也分为两部分调用operator delete 调用析构函数;
//
//总结在C中申请和释放堆上的空间就用new 和 delete3.2 实现专属operator new 与 operator delete (了解)
//注意一般情况下不需要对 operator new 和 operator delete 进行重载除非在申请和释放空间的时候具有某些特殊的要求。比如在使用new和delete
// 申请和释放空间时打印一些日志信息来简单帮助用户检测是否存在内存泄漏。
//
//当我们不写自己专属的operator new函数和 operator delete函数的时候new和delete 会自动调用C库里面的operator new函数和 operator delete函数。
//当我们自己写专属的operator new函数和 operator delete函数时new和delete 会调用专属的operator new函数和 operator delete函数来实现某些特殊的需求。// new - operator new 构造函数
// 默认情况下operator new使用全局库里面的。
// 但每个类可以去实现自己专属operator new; new这个类对象它就会调用自己实现的这个operator new//实现类专属的operator new优先调用
struct ListNode
{int _val;ListNode* _next;//内存池static allocatorListNode alloc;void* operator new(size_t n){cout operator new - STL内存池allocator申请 endl;void* obj alloc.allocate(1);return obj;}void operator delete(void* ptr){cout operator delete - STL内存池allocator申请 endl;alloc.deallocate((ListNode*)ptr,1);}//构造函数struct ListNode(int val):_val(val),_next(nullptr){}
};内存池的定义
allocatorListNode ListNode::alloc;int main()
{//频繁地申请 ListNode想提高效率 —— 申请ListNode时不去malloc,而是自己定制内存池。ListNode* node1 new ListNode(1); //new先去调用 类里面的operator new ,如果类里面没有operator new,就会去库里面调用。ListNode* node2 new ListNode(2);ListNode* node3 new ListNode(3);delete node1;delete node2;delete node3;return 0;
}