• C++ 【new,delete内存管理】


    目录

    1. C/C++内存分布

    2.new和delete操作符

    3. operator new与operator delete函数


    1. C/C++内存分布

    程序编译好的二进制指令代码在程序运行时加载到代码段中,并在main函数开辟时,栈区和堆区数据会根据运行代码进行相对应空间开辟。

    堆向上生长:先建立堆的地址小于后建立堆的地址

    栈向下生长:先调用栈帧的地址比后调用的地址大

    常量区被硬件保护,里面的内容不能被修改

    练习题


    2.new和delete操作符

     针对内置类型new ~=malloc,delete~=free,只有用法区别

    new 和 delete针对的更多是自定义类型

     new的申请

    1. void testnew1()
    2. {
    3. int* p1 = new int;//后面的int是类型,申请一个int对象的堆空间
    4. int* p2 = new int[10];//开10个int大小堆空间
    5. int* p2p = new int[5]{ 1,2,3,4,5 }; //C98不支持对new数组初始化,C11支持,剩下没初始化值默认为0
    6. int* p3 = new int(5);//初始化一个int,值为5
    7. }

    delete释放

    注意事项:

    1.匹配使用new和delete操作符;申请和释放连续的数组空间,使用 new[]和delete[]

    1. void testnew1()
    2. {
    3. int* p1 = new int;//后面的int是类型,申请一个int对象的堆空间
    4. int* p2 = new int[10];//开10个int大小堆空间
    5. int* p2p = new int[5]{ 1,2,3,4,5 };
    6. int* p3 = new int(5);//初始化一个int,值为5
    7. delete p1;
    8. delete[] p2;
    9. delete[] p2p;
    10. delete p3;
    11. }

    3.new/delete 和 malloc/free最大区别是 new/delete对于【自定义类型】除了开空间 new会调用默认 构造函数,delete会调用析构函数,而malloc与 free不会。

    符合后定义先析构

    new失败抛异常

    malloc失败返回nullptr,new失败不需要检查返回值

    1. int main()
    2. {
    3. try
    4. {
    5. int* p1 = new int[1024*1024*10];
    6. }
    7. catch (const exception&e)
    8. {
    9. cout << e.what() << endl;
    10. }
    11. return 0;
    12. }


    3. operator new与operator delete函数

    new会开空间和调用构造函数,而在堆上开空间调用operator new,调用构造函数调用A::A

    operator new不是对new运算符重载,operator new 和operator delete是系统提供的全局函数

    operator new底层还是调用了malloc,只是对malloc封装+抛异常+调用构造函数处理

    operator delete底层还是调用了free,加上了内存越界等机制

    重载operator new与operator delete(不是运算符和函数重载)

    不写默认调用库中函数,写了调用我们重载的函数

    使用场景:

    1.在使用new和delete申请和释放空间时,打印一些日志信息, 以简单帮助用户来检测是否存在内存泄漏

    2.重载专属的operator new(例如内存池)

    3.默认情况下使用全局库的operator new,但每个类可以有自己的operator new,就会调用自己写的

    定位new

    在已分配的原始内存空间中,显示调用构造函数初始化一个对象

    使用格式:new (指针) type(参数)

    1. int main()
    2. {
    3. int* p1 = new int;
    4. new(p1)int(1);
    5. return 0;
    6. }

    使用场景: 定位new表达式在实际中一般是配合内存池使用。因为内存池分配出的内存没有初始化,所以如果是自定义类型的对象,需要使用new的定义表达式进行显示调构造函数进行初始化即可使用

  • 相关阅读:
    冥想第九百七十八天
    ChatGPT调教指南 | 咒语指南 | Prompts提示词教程(二)
    array.some()详解
    excel相同行不同列查询
    基于 SpringBoot + MyBatis 的在线音乐播放器
    Java学习笔记——枚举
    OpenCV+QT实现的数字图像处理算法合集
    IgH详解十二、IgH实现使用ENI文件配置从站(一)
    [从零开始学习FPGA编程-47]:视野篇 - 第三代半导体技术现状与发展趋势
    TCP连接
  • 原文地址:https://blog.csdn.net/weixin_63543274/article/details/126264338