1. C/C++内存分布
- 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(ptr3);
- }
复制代码 这段代码涉及了C/C++中步伐内存地区划分,假如可以清晰的知道每个变量和只读常量所在C/C++中步伐内存地区的位置阐明还是可以的。
一样平常在函数内创建的变量都是在栈区的,假如是static变量不论在那创建都是在数据段(静态区),对于ptr1这样的用于指向动态开辟的内存空间的变量,他本身在出栈时会被开释,但是他所指向的空间并不会在出栈时被开释。
阐明:
1.栈又叫堆栈--非静态局部变量/函数参数/返回值等等,栈是向下增长的。
2.内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库,用户可使用体系接口创建共享内存,做进程间通讯。
3.堆用于步伐运行时动态内存分配,堆是向上生长的
4.数据段--存储全局变量和静态数据
5.代码段--可实行的代码/只读常量
2.C/C++中内存管理方式
2.1 C的内存管理方式
- void Test()
- {
- int *p1 = (int *)malloc(sizeof(int));
- free(p1);
- int *p2 = (int *)calloc(4, sizeof(int));
- int *p3 = (int *)realloc(p2, sizeof(int) * 10);
- free(p3);
- }
复制代码 你们可以思考一下上面这段这段代码中p2是否需要开释,实在是不需要开释的因为realloc对于p2会做修改让p2指向新空间的开始。realloc的扩容机制并不是追加而是寻找符合的空间将原数据拷贝到新空间,然后将原来的指针指向新开的空间。
2.2 C++内存管理的方式
相对于C而言C++内存管理的接口就比力少了只有两个一个new一个delete,C++与C内存管理最大的差异在于C++的new假如是自界说范例会调用相应的构造函数,delete会调用自界说范例的析构函数。
- void Test()
- {
- // 动态申请一个int类型的空间
- int *ptr4 = new int;
- // 动态申请一个int类型的空间并初始化为10
- int *ptr5 = new int(10);
- // 动态申请10个int类型的空间
- int *ptr6 = new int[10];
- delete ptr4;
- delete ptr5;
- delete[] ptr6;
- }
复制代码
注意:申请和开释单个元素的空间,使用new和delete操作符,申请和开释一连的空间,使用new[]和delete[]一定要匹配起来用
3.operator new与operator delete函数
new和delete是用户进行动态内存申请和开释的操作符,operator new和operator delete是体系提供的全局函数,new在底层调用oprator new全局函数来申请空间,delete在底层通过operator delete全局函数开释空间
- /*
- operator new:该函数实际通过malloc来申请空间,当malloc申请空间成功时直接返回;申请空间失败,
- 尝试执行空 间不足应对措施,如果改应对措施用户设置了,则继续申请,否则抛异常。
- */
- void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
- {
- // try to allocate size bytes
- void *p;
- while ((p = malloc(size)) == 0)
- if (_callnewh(size) == 0)
- {
- // report no memory
- // 如果申请内存失败了,这里会抛出bad_alloc 类型异常
- static const std::bad_alloc nomem;
- _RAISE(nomem);
- }
- return (p);
- }
- /*
- operator delete: 该函数最终是通过free来释放空间的
- */
- void operator delete(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_FINALLY
- return;
- }
- /*
- free的实现
- */
- #define free(p) _free_dbg(p, _NORMAL_BLOCK)
复制代码 通过上述两个全局函数的实现知道,operator new实际也是通过malloc来申请空间,假如malloc申请空间成功就直接返回,否则实行用户提供的空间不足应对措施,假如用户提供该措施就继续申请,否则就抛异常。operator delete终极是通过free来开释空间的。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |