• 【C++】5.C语言/C++内存管理


    一、C/C++内存分布   

                         栈中存储的是局部变量,函数参数,返回值等

            堆主要用于动态内存分配

            数据段用以存储全局数据和静态数据

            代码段存储可执行代码和常量

    二、C语言和C++中的内存管理方式

            在C语言中,我们使用 malloc、calloc、realloc、free来进行动态内存管理。而在C++中这些方法仍可以继续使用,但是在面对自定义类型对象的创建时显得无能为力了,因此C++引入了new和delete操作符

            2.1、内置类型的内存管理 

    1. int main()
    2. {
    3. int* a = new int;//创建整型变量a
    4. delete a;
    5. int* b = new int(5);//创建整型变量b,并初始化为5
    6. delete b;
    7. int* arr = new int[10] {0,1,2};//创建整型数组,并将其初始化
    8. delete[] arr;
    9. return 0;
    10. }

            2.2、自定义类型的内存管理

            在内置类型中,C语言的malloc和free与C++中的new和delete使用起来差别并不大。但是在自定义类型中,new和delete就很重要了。原因就在于,在自定义类型中,new和delete可以分别调用构造函数和析构函数来对对象完成初始化和资源清理。

    1. int main()
    2. {
    3. // new / delete 和 malloc / free最大区别是 new / delete对于【自定义类型】除了开空间还会调用构造函数和析构函数
    4. A* p1 = (A*)malloc(sizeof(A));
    5. A* p2 = new A(1);
    6. free(p1);
    7. delete p2;
    8. // 内置类型是几乎是一样的
    9. int* p3 = (int*)malloc(sizeof(int)); // C
    10. int* p4 = new int;
    11. free(p3);
    12. delete p4;
    13. A* p5 = (A*)malloc(sizeof(A) * 10);
    14. A* p6 = new A[10];
    15. free(p5);
    16. delete[] p6;
    17. return 0;
    18. }

    三、operator new与operator delete函数

            new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。

    具体的源码如下

    1. void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
    2. {
    3. // try to allocate size bytes
    4. void *p;
    5. while ((p = malloc(size)) == 0)
    6.     if (_callnewh(size) == 0)
    7.     {
    8.         // report no memory
    9.         // 如果申请内存失败了,这里会抛出bad_alloc 类型异常
    10.         static const std::bad_alloc nomem;
    11.         _RAISE(nomem);
    12.     }
    13. return (p);
    14. }
    15. /*
    16. operator delete: 该函数最终是通过free来释放空间的
    17. */
    18. void operator delete(void *pUserData)
    19. {
    20.     _CrtMemBlockHeader * pHead;
    21.     RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
    22.     if (pUserData == NULL)
    23.         return;
    24.     _mlock(_HEAP_LOCK);  /* block other threads */
    25.     __TRY
    26.         /* get a pointer to memory block header */
    27.         pHead = pHdr(pUserData);
    28.          /* verify block type */
    29.         _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
    30.         _free_dbg( pUserData, pHead->nBlockUse );
    31.     __FINALLY
    32.         _munlock(_HEAP_LOCK);  /* release other threads */
    33.     __END_TRY_FINALLY
    34.     return;
    35. }
    36. /*
    37. free的实现
    38. */
    39. #define   free(p)               _free_dbg(p, _NORMAL_BLOCK)

    可以了解到operator new 实际也是通过malloc来申请空间,如果 malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的。

  • 相关阅读:
    【实操】基于ChatGPT构建知识库
    【linux实用命令】
    Xray是什么
    SSM教室预约管理系统
    Jmeter常用的两大性能测试场景你都知道吗?
    python线程安全队列讲解
    PyCharm 出现卡顿解决方案
    atoi函数及其模拟实现
    MySQL数据库管理
    坐标系下的运动旋量转换
  • 原文地址:https://blog.csdn.net/2301_80258336/article/details/138162437