C语言与C++中内存管理详解
主要段及其分布 每个程序运行起来以后它将拥有自己独立的虚拟地址空间。这个虚拟地址空间的大小与操作系统的位数有关系。32位硬件平台的虚拟地址空间的地址可以从0~2^32-1,即0x00000000~0xFFFFFFFF,总共4GB大小。64位硬件平台的虚拟地址空间则会很大。C/C程序在虚拟内存中的排布大概如下所示仅仅列出了相关的主要段如上图所示1、栈区stack— 由编译器自动分配释放 存放函数的参数值局部变量的值等。其操作方式类似于数据结构中的栈。2、堆区heap — 一般由程序员分配释放 若程序员不释放程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事分配方式倒是类似于链表注意不释放的话会造成内存泄漏。3、数据段静态区static—全局变量和静态变量的存储是放在一块的初始化的全局变量和静态变量在一块区域 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后由系统释放。4、内存映射段是高效的I/O映射方式用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存做进程间通信。5、代码段—存放函数体的二进制代码直接的操作数也是存储在这个位置的。如int a4;。动态内存管理方式-堆区C语言动态内存管理C语言中使用malloc/calloc/realloc/free四个函数来进行动态内存管理1、malloc用来动态申请一块内存但不初始化。2、calloc: 动态申请一块内存但会将申请出的内存初始化为0。3、realloc: 当申请出的内存不够用时会使用realloc来动态扩容会有一定程度的消耗。4、free 用来释放动态申请的的内存(当内存不用时一定要使用free来释放它否则会造成内存泄漏)C动态内存管理 因为C是兼容C的也可以使用上述的几个函数来进行内存管理但是C中引入了new/delete两个操作符来进行内存的申请和释放。new和delete的用法1、操作内置类型123456789101112//申请单个对象int*p1newint;//动态申请一块int类型的空间。int*p2newint(3);//动态申请一块int类型的空间并将其初始化。deletep1;deletep2;//动态申请一块连续空间int*p3newint[10];//[]中是对象个数//释放delete[] p3;注意申请和释放单个元素的空间使用new和delete操作符申请和释放连续的空间使用new[]和delete[]。2、操作自定义类型123456789101112131415161718192021222324252627classTest{public:Test(): _data(0){coutTest():thisendl;}~Test(){cout~Test():thisendl;}private:int_data;};intmain(){//申请单个自定义类型的空间Test* p1newTest;deletep1;//申请多个自定义类型的连续空间Test* p2newTest[10];delete[] p2;return0;}注意在申请自定义类型的空间时new会调用构造函数delete会调用析构函数而malloc与free不会。operator new与operator delete函数new和delete是用户进行动态内存申请和释放的操作符operator new和operator delete是系统提供的全局函数new在底层调用operator new全局函数来申请空间delete在底层通过operator delete全局函数来释放空间。operator new:该函数实际通过malloc来申请空间当malloc申请空间成功时直接返回申请空间失败尝试执行空间不足应对措施如果改应对措施用户1设置了则继续申请否则抛异常。1234567891011121314void*__CRTDECL operatornew(size_tsize) _THROW1(_STD bad_alloc){// try to allocate size bytesvoid*p;while((p malloc(size)) 0)if(_callnewh(size) 0){// report no memory// 如果申请内存失败了这里会抛出bad_alloc 类型异常staticconststd::bad_alloc nomem;_RAISE(nomem);}return(p);}operator delete:该函数实际通过free来释放空间的。123456789101112131415161718voidoperatordelete(void*pUserData){_CrtMemBlockHeader * pHead;RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));if(pUserData NULL)return;_mlock(_HEAP_LOCK);/* block other threads */__TRY/* get a pointer to memory block header */pHead pHdr(pUserData);/* verify block type */_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead-nBlockUse));_free_dbg( pUserData, pHead-nBlockUse );__FINALLY_munlock(_HEAP_LOCK);/* release other threads */__END_TRY_FINALLYreturn;}new和delete的实现原理1、内置类型 如果申请的是内置类型的空间new和mallocdelete和free基本类似不同的地方是new/delete申请和释放的是单个元素的空间new[]和delete[]申请的是连续空间而且new在申请空间失败时会抛异常malloc会返回NULL2、自定义类型new的原理1、调用operator new 函数申请空间2、在申请的空间上执行构造函数完成对象的构造delete的原理1、调用operatordelete 函数释放空间2、在空间上执行析构函数完成对象中资源的清理工作new T[N]的原理1、调用operator new[]函数在operator new[]中实际调用operator new函数完成N个对象空间的申请2、在申请的空间上执行N次构造函数delete[]的原理1、在释放的对象空间上执行N次析构函数完成N个对象中资源的清理2、调用operator delete[]释放空间实际在operator delete[]中调用operator delete来释放空间