一、C/C内存区域划分1. 栈又叫堆栈--非静态局部变量/函数参数/返回值等等栈是向下增长的。2. 内存映射段是高效的I/O映射方式用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存做进程间通信。3. 堆用于程序运行时动态内存分配堆是可以上增长的。4. 数据段--存储全局数据和静态数据。5. 代码段--可执行的代码/只读常量。二、常见变量存储区域123456789101112131415intglobalVar 1;//全局变量中在静态区staticintstaticGlobalVar 1;//静态区voidTest(){staticintstaticVar 1;//静态区intlocalVar 1;//栈区intnum1[10] { 1, 2, 3, 4 };//栈区charchar2[] abcd;//栈区*char2在栈区constchar* pChar3 abcd;//指针在栈区*pchar3在常量区int* ptr1 (int*)malloc(sizeof(int) * 4);//指针在栈区*ptr1在堆区int* ptr2 (int*)calloc(4,sizeof(int));///栈区int* ptr3 (int*)realloc(ptr2,sizeof(int) * 4);//栈区free(ptr1);free(ptr3);}三、new和delete1、new和delete的使用方式12345678910111213intmain(){int* p1 newint;//在堆区申请一个int大小的空间不会初始化int* p2 newint(0);//申请并初始化为0deletep1;deletep2;int* p3 newint[10];//在堆区申请一块10个int大小的空间未初始化int* p4 newint[10]{ 1,2,3,4 };//初始化为{1,2,3,4,0,0,0,0,0,0}delete[] p3;delete[] p4;return0;}注意申请和释放单个元素的空间使用new和delete操作符申请和释放连续的空间使用new[]和delete[]一定要匹配起来使用。2、new、delete和malloc、free的区别1、对于内置类型没有区别。2、new和delete是C的关键字/操作符而malloc和free是C语言的库函数。3、对于自定义类型相比于malloc和freenew和delete会额外调用类中的构造函数和析构函数。4、malloc的返回值是void*使用时需要强转new后边跟的是空间的类型所以new不需要强转。5、malloc失败返回空指针需要判空new失败抛异常需要捕获异常。3、new的原理new等于operator new()构造函数。operator new()不是new运算符的重载因为参数没有自定义类型。它是一个库里的全局函数。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 new()是对malloc的封装如果malloc失败将会抛出异常。4、delete的原理delete等于operator delete()析构函数12345678910111213141516171819//operator delete: 该函数最终是通过free来释放空间的voidoperatordelete(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 );//调用free()__FINALLY_munlock(_HEAP_LOCK);/* release other threads */__END_TRY_FINALLYreturn; }//free的实现#define free(p) _free_dbg(p, _NORMAL_BLOCK)从底层代码可以看出operator delete()调用了free。所以针对内置类型或无资源的类对象delete时使用delete和free效果相同。但对于有资源需要释放的对象时直接使用free虽然释放了对象的空间但对象内部的资源还未被清理导致内存泄漏这种情况必须使用delete。5、new T[N]原理1、new T[N]调用operator new[]2、operator new[]调用operator new完成N个对象空间的开辟。3、调用N次构造函数完成N个对象的初始化。6、delete[]原理1、调用N次析构函数完成N个对象资源的清理工作。2、调用operator delete[]3、operator delete[]调用operator delete完成整段空间的释放。四、定位new1、定位new的概念对于一个类我们可以显式的去调用类的析构函数但是不能显式调用构造函数那么使用定位new就可以显式调用类的构造函数对一块空间重新初始化。
C++中动态内存管理和泛型编程
一、C/C内存区域划分1. 栈又叫堆栈--非静态局部变量/函数参数/返回值等等栈是向下增长的。2. 内存映射段是高效的I/O映射方式用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存做进程间通信。3. 堆用于程序运行时动态内存分配堆是可以上增长的。4. 数据段--存储全局数据和静态数据。5. 代码段--可执行的代码/只读常量。二、常见变量存储区域123456789101112131415intglobalVar 1;//全局变量中在静态区staticintstaticGlobalVar 1;//静态区voidTest(){staticintstaticVar 1;//静态区intlocalVar 1;//栈区intnum1[10] { 1, 2, 3, 4 };//栈区charchar2[] abcd;//栈区*char2在栈区constchar* pChar3 abcd;//指针在栈区*pchar3在常量区int* ptr1 (int*)malloc(sizeof(int) * 4);//指针在栈区*ptr1在堆区int* ptr2 (int*)calloc(4,sizeof(int));///栈区int* ptr3 (int*)realloc(ptr2,sizeof(int) * 4);//栈区free(ptr1);free(ptr3);}三、new和delete1、new和delete的使用方式12345678910111213intmain(){int* p1 newint;//在堆区申请一个int大小的空间不会初始化int* p2 newint(0);//申请并初始化为0deletep1;deletep2;int* p3 newint[10];//在堆区申请一块10个int大小的空间未初始化int* p4 newint[10]{ 1,2,3,4 };//初始化为{1,2,3,4,0,0,0,0,0,0}delete[] p3;delete[] p4;return0;}注意申请和释放单个元素的空间使用new和delete操作符申请和释放连续的空间使用new[]和delete[]一定要匹配起来使用。2、new、delete和malloc、free的区别1、对于内置类型没有区别。2、new和delete是C的关键字/操作符而malloc和free是C语言的库函数。3、对于自定义类型相比于malloc和freenew和delete会额外调用类中的构造函数和析构函数。4、malloc的返回值是void*使用时需要强转new后边跟的是空间的类型所以new不需要强转。5、malloc失败返回空指针需要判空new失败抛异常需要捕获异常。3、new的原理new等于operator new()构造函数。operator new()不是new运算符的重载因为参数没有自定义类型。它是一个库里的全局函数。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 new()是对malloc的封装如果malloc失败将会抛出异常。4、delete的原理delete等于operator delete()析构函数12345678910111213141516171819//operator delete: 该函数最终是通过free来释放空间的voidoperatordelete(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 );//调用free()__FINALLY_munlock(_HEAP_LOCK);/* release other threads */__END_TRY_FINALLYreturn; }//free的实现#define free(p) _free_dbg(p, _NORMAL_BLOCK)从底层代码可以看出operator delete()调用了free。所以针对内置类型或无资源的类对象delete时使用delete和free效果相同。但对于有资源需要释放的对象时直接使用free虽然释放了对象的空间但对象内部的资源还未被清理导致内存泄漏这种情况必须使用delete。5、new T[N]原理1、new T[N]调用operator new[]2、operator new[]调用operator new完成N个对象空间的开辟。3、调用N次构造函数完成N个对象的初始化。6、delete[]原理1、调用N次析构函数完成N个对象资源的清理工作。2、调用operator delete[]3、operator delete[]调用operator delete完成整段空间的释放。四、定位new1、定位new的概念对于一个类我们可以显式的去调用类的析构函数但是不能显式调用构造函数那么使用定位new就可以显式调用类的构造函数对一块空间重新初始化。