C++---内存管理

打印 上一主题 下一主题

主题 1844|帖子 1844|积分 5532

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
1 C/C++内存分布

栈区:由编译器自动分配和开释,存放运行时间的局部变量,函数参数,返回数据,返回地点。
堆区:一般由步调员自己分配,然后自己开释,例如栈的实现malloc开辟的数组空间。
数据段(静态区):存放全局变量,静态数据,常量,步调结束后自动开释。
代码段(常量区):存放常量字符串和可执行代码,步调结束自动开释。
2 C语言中动态内存管理方式:malloc/calloc/realloc/free

malloc:开辟空间,不初始化 (int*)malloc(sizeof(int)):开辟一个int巨细的空间。
calloc:开辟空间并把每个字节初始化为0。(int*)calloc(4,sizeof(int)):开辟4个int巨细的空间。
realloc(用于扩容):在内存找一段连续巨细的空间,将传入的指针指向的内存内的字节全部拷贝过来,然后开释原指针空间,再把新巨细的空间指针返回。(int*)realloc(_ptr,sizeof(int)*10)。
free:开释一段连续空间。free(_ptr),开释完之和_ptr为野指针,一般必要_ptr=NULL。
3 C++内存管理实现

C语言内存管理方式在C++中可以继承使用,但有些地方就无能为力,而且使用起来比较贫苦,因此C++又提出了自己的内存管理方式:通过new和delete操作符举行动态内存管理。
在对内置范例开辟空间时new和malloc实质上是没什么区别的,但在对自定义类对象举行空间开辟时间,new和malloc的区别在于malloc只负责开辟空间不会举行初始化,而new开辟空间的同时会调用自定义类内的构造函数举行初始化。

 

注意:申请和开释单个元素的空间,使用new和delete操作符,申请和开释连续的空间,使用new[]和delete[],注意:匹配起来使用。
new/delete和malloc/free最大的区别在于,new/delete开辟空间会调用构造函数,结束会调用析构函数。而malloc/free不会。
operator new与operator delete

new和delete是用户举行动态内存申请和开释的操作符,operator new 和operator delete是体系提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来开释空间。
  1. /*
  2. operator new:该函数实际通过malloc来申请空间,当malloc申请空间成功时直接返回;申请空间失败,
  3. 尝试执行空
  4. 间不足应对措施,如果改应对措施用户设置了,则继续申请,否则抛异常。
  5. */
  6. void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
  7. {
  8.     // try to allocate size bytes
  9.     void *p;
  10.     while ((p = malloc(size)) == 0)
  11.     if (_callnewh(size) == 0)
  12.     {
  13.         // report no memory
  14.         // 如果申请内存失败了,这里会抛出bad_alloc 类型异常
  15.         static const std::bad_alloc nomem;
  16.         _RAISE(nomem);
  17.     }
  18.     return (p);
  19. }
  20. /*
  21. operator delete: 该函数最终是通过free来释放空间的
  22. */
  23. void operator delete(void *pUserData)
  24. {
  25.     _CrtMemBlockHeader * pHead;
  26.     RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
  27.     if (pUserData == NULL)
  28.         return;
  29.     _mlock(_HEAP_LOCK); /* block other threads */
  30.     __TRY
  31.     /* get a pointer to memory block header */
  32.     pHead = pHdr(pUserData);
  33.     /* verify block type */
  34.     _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
  35.     _free_dbg( pUserData, pHead->nBlockUse );
  36.     __FINALLY
  37.     _munlock(_HEAP_LOCK); /* release other threads */
  38.     __END_TRY_FINALLY
  39.     return;
  40. }
  41. /*
  42. free的实现
  43. */
  44. #define free(p) _free_dbg(p, _NORMAL_BLOCK)
复制代码
通过上述两个全局函数的实现知道,operator new 实际也是通过malloc来申请空间,假如malloc申请空间乐成就直接返回,否则执行用户提供的空间不足应对措施,假如用户提供该措施就继承申请,否则就抛异常。operator delete 最终是通过free来开释空间的。
说白了operator new就是new子过程,new就等价于operator new之和在调用构造函数。而operator new在步调设计上又是由malloc为基础,区别于malloc的就是malloc申请空间失败之和返回值是0。而operator new申请空间失败后是直接抛异常。


定位new表达式

定位new表达式在实际中一般是配合内存池使用。因为内存池分配出的内存没有初始化,以是假如是自定义范例的对象,必要使用new的定义表达式举行表现调构造函数举行初始化。

我们用malloc为p3开辟一个结构体巨细的空间后,成员变量并没有初始化,但由于成员变量为private修饰的在外不可访问,这时间就可以使用定位new去举行初始化。

定位new格式为new(变量)+类名(初始化)。
malloc/free与new/delete的区别
共同点是都在堆上申请空间,必要用户手动开释。
区别是malloc/free是函数而new/delete是操作符。
malloc/free使用时间只开辟空间和烧毁空间,而new/delete开辟空间会调用构造函数初始化,烧毁空间会调用析构函数。
malloc返回值是void*使用时间必要强转范例,而new不用,编译器自动辨认。
malloc申请空间失败返回的是NULL,而new申请空间失败会抛异常。
内存泄露

什么是内存泄漏:内存泄漏指因为疏忽或错误造成步调未能开释已经不再使用的内存的环境。内存泄漏并不是指内存在物理上的消散,而是应用步调分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。 
内存泄漏的危害:长期运行的步调出现内存泄漏,影响很大,如操作体系、后台服务等等,出现内存泄漏会导致相应越来越慢,最终卡死。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

愛在花開的季節

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表