• C/C++内存管理


    目录

    C/C++内存分布

    C语言中动态内存管理

    C++内存管理方式 

    new/delete用法

    operator new 与operator delete函数

    new和delete的实现原理

    常见面试题

    C/C++内存分布

     关于C/C++内存分布在另一篇博客写过,详情见点击

    C语言中动态内存管理

    用malloc/calloc/realloc和free这四个函数申请释放堆上内存,在另一篇博客中写过,详情见点击

    C++内存管理方式 

    C 语言内存管理方式在 C++ 中可以继续使用,但有些地方就无能为力而且使用起来比较麻烦,因此 C++ 又提出 了自己的内存管理方式:通过 new delete 操作符进行动态内存管理

    new/delete用法

    1、申请和释放单个元素的空间,使用newdelete操作符,申请和释放连续的空间,使用new [ ]和delete [ ] 

    2、在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数

    3、new申请空间失败会抛异常,malloc申请空间失败会返回NULL

    1. class Test
    2. {
    3. public:
    4. Test()
    5. : _data(0)
    6. {
    7. cout << "Test():" << this << endl;
    8. }
    9. ~Test()
    10. {
    11. cout << "~Test():" << this << endl;
    12. }
    13. private:
    14. int _data;
    15. };
    16. int main ()
    17. {
    18. // 申请单个Test类型的对象
    19. Test* p1 = new Test;
    20. delete p1;
    21. // 申请10个Test类型的对象
    22. Test* p2 = new Test[3];
    23. delete[] p2;
    24. system("pause");
    25. return 0;
    26. }

     

    operator new 与operator delete函数

    1、new delete 是用户进行 动态内存申请和释放的操作符
    2、operator new operator delete是系统提供的 全局函数。operator new底层用malloc实现,operator delete底层用free实现,区别在于operator new中malloc申请空间成功时直接返回内存首地址,申请失败会尝试执行空间不足应对措施,如果我们提供了应对策略,则继续尝试申请,否则抛出异常。
    3、 new 在底层调用 operator new 全局函数来申请空间, delete 在底层通过 operator delete 全局函数来释放空间。

    new和delete的实现原理

    内置类型

    如果申请的是内置类型的空间, new malloc delete free 基本类似,不同的地方是: new/delete 申请和 释放的是单个元素的空间,new[] delete[] 申请的是连续空间,而且 new 在申请空间失败时会抛异常,malloc会返回 NULL
    自定义类型:
    new 的原理
    • 调用operator new函数申请空间
    • 在申请的空间上执行构造函数,完成对象的构造
    delete的原理
    • 在空间上执行析构函数,完成对象中资源的清理工作
    • 调用operator delete函数释放对象的空间
    new T[N]的原理
    • 调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对象空间的申请
    • 在申请的空间上执行N次构造函数
    delete[]的原理
    • 在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理
    • 调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释放空间

    常见面试题

    malloc/free new/delete 的区别 (1-4为用法上的区别,5-6为底层上的区别)
    malloc/free new/delete 的共同点是:都是从堆上申请空间,并且需要用户手动释放。不同的地方是:
    1. mallocfree是函数,newdelete是操作符
    2. malloc申请的空间不会初始化,new可以初始化
    3. malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可
    4. malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型
    5. malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需要捕获异常
    6. 申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理
    什么是内存泄漏,内存泄漏的危害
    • 什么是内存泄漏:内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。
    • 内存泄漏的危害:长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现内存泄漏会导致响应越来越慢,最终卡死。
    如何避免内存泄漏
    1. 工程前期良好的设计规范,养成良好的编码规范,申请的内存空间记着匹配的去释放。ps:这个理想状态。但是如果碰上异常时,就算注意释放了,还是可能会出问题。需要下一条智能指针来管理才有保证。
    2. 采用RAII思想或者智能指针来管理资源。
    3. 有些公司内部规范使用内部实现的私有内存管理库。这套库自带内存泄漏检测的功能选项。
    4. 出问题了使用内存泄漏工具检测。ps:不过很多工具都不够靠谱,或者收费昂贵。
    总结一下:
    内存泄漏非常常见,解决方案分为两种:
    1. 事前预防型。如智能指针等。
    2. 事后查错型。如泄漏检测工具。
  • 相关阅读:
    如何设计实现系统应支持至少300个并行用户的同时访问和使用的需求
    单例模式(Singleton)
    【IoT】产品经理:如何了解行业需求、痛点和发展机会?
    【字符串】分割字符串的最大得分
    解决passwd:Authentication token manipulation error
    人机交互复习专题
    HTML-表格、表单和CSS初识,选择器,书写规范
    百亿数据百亿花, 库若恒河沙复沙,Go lang1.18入门精炼教程,由白丁入鸿儒,Go lang数据库操作实践EP12
    基于Java的课程管理系统
    4.小程序9类组件和三类api
  • 原文地址:https://blog.csdn.net/xiaoming1999/article/details/126449076