C++从入门到实战(十二)详细讲解C++如何实现内存管理

06-02 1651阅读

C++从入门到实战(十二)详细讲解C++如何实现内存管理

  • 前言
  • 一、C++内存管理方式
    • 1. new/delete操作内置类型
    • 2. 异常与内存管理的联系(简单了解)
    • 3. new和delete操作自定义类型
    • 二、 operator new与operator delete函数(重点)
      • 1. new和delete操作符与operator new和operator delete函数的关系
      • 2. operator new函数的工作原理
      • 3. operator delete函数的工作原理
      • 三、 定位new表达式(placement-new) (了解即可)
        • 1. 定位 new 表达式的概念
        • 2. 定位 new 表达式的使用格式
        • 3. 定位 new 表达式的使用场景
        • 四、malloc/free和new/delete的区别
          • 1. 相同点
          • 2. 不同点
            • 一个是函数,一个是操作符
            • new 会 “初始化”,malloc 不会
            • 空间大小:new 自动计算,malloc 要手动算
            • new 不用强转,malloc 需要
            • 错误处理:malloc 返 NULL,new 抛异常
            • 自定义类型:new/delete 会 “照顾” 对象,malloc/free 不会

              前言

              • 在上一篇博客中,我们探讨了 C/C++ 语言的内存分布模型,并对比了 C 与 C++ 内存管理的核心差异,初步认识了 C++ 中new与delete的基本概念,为理解 C++ 内存管理体系奠定了基础。
              • 本文将在此基础上,深入解析 C++ 内存管理的核心机制,从底层原理到实践细节展开系统讲解,帮助读者全面掌握这一重要知识模块。

                我的个人主页,欢迎来阅读我的其他文章

                https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343

                我的C++知识文章专栏

                欢迎来阅读指出不足

                https://blog.csdn.net/2402_83322742/category_12880513.html?spm=1001.2014.3001.5482


                一、C++内存管理方式

                1. new/delete操作内置类型

                • 在 C 语言里有它自己的内存管理办法,但用起来比较麻烦,而且有些情况处理不了。
                • C++ 为了解决这些问题,引入了new和delete操作符来进行动态内存管理。
                  #include 
                  using namespace std;
                  void Test()
                  {
                  	int* ptr4 = new int;
                  	// 动态申请一个int类型的空间
                  	int* ptr5 = new int(10);
                  	//动态申请一个int类型的空间并初始化为10
                  	int* ptr6 = new int[3];
                  	//动态申请3个int类型的空间
                  	delete ptr4;
                  	delete ptr5;
                  	//delete ptr6;//错误在 C++ 中,new 和 delete、new[] 和 delete[] 是成对出现的操作符,它们的使用需要遵循特定的配对规则:
                  	//如果使用 delete 而非 delete[] 来释放通过 new[] 分配的数组内存,会产生严重的后果:
                  	//内存泄漏:delete 只会释放数组首元素的内存,而不会释放数组中其他元素的内存,这就导致了部分内存无法被回收,造成内存泄漏。
                  	//未定义行为:使用 delete 释放数组内存属于未定义行为,这意味着程序可能会出现各种不可预测的问题,比如程序崩溃、数据损坏等
                  	
                  	delete[] ptr6;
                  }
                  
                  • 在 C++ 中,new 和 delete、new[] 和 delete[] 是成对出现的操作符,它们的使用需要遵循特定的配对规则:
                  • 如果使用 delete 而非 delete[] 来释放通过 new[] 分配的数组内存,会产生严重的后果:例如上面代码中的int* ptr6 = new int[3]与delete ptr6

                    内存泄漏:delete 只会释放数组首元素的内存,而不会释放数组中其他元素的内存,这就导致了部分内存无法被回收,造成内存泄漏。

                    未定义行为:使用 delete 释放数组内存属于未定义行为,这意味着程序可能会出现各种不可预测的问题,比如程序崩溃、数据损坏等

                    C++从入门到实战(十二)详细讲解C++如何实现内存管理

                    2. 异常与内存管理的联系(简单了解)

                    • 在使用new申请内存时,如果系统没有足够的内存可供分配,就可能会抛出异常。
                    • 所以在进行内存管理时,要考虑到这种可能出现的异常情况,确保程序的健壮性。
                      #include 
                      using namespace std;
                      void Test() {
                          try {
                              // 动态申请一个 int 类型的空间
                              int* ptr4 = new int;
                              // 动态申请一个 int 类型的空间并初始化为 10
                              int* ptr5 = new int(10);
                              // 动态申请 3 个 int 类型的空间
                              int* ptr6 = new int[3];
                              // 使用分配的内存
                              *ptr4 = 5;
                              cout 
                                  ptr6[i] = i;
                                  cout 
                              // 捕获内存分配失败的异常
                              cerr 
                          Test();
                          return 0;
                      }    
                      
                          int i = 1;
                          while (1)
                          {
                              int* p1 = new int[1024 * 1024];
                              cout 
                          try
                          {
                              Func();
                          }
                          catch (const std::exception& e)
                          {
                              cout 
                      public:
                      	Person(const char* _name,int _age)
                      	{
                      		name = _name;
                      		age = _age;
                      		cout 
                      		cout 
                      	// 使用 new 创建 Person 对象
                      	Person* person = new Person("Alice", 25);
                      	// 使用 delete 释放对象内存
                      	delete person;
                          return 0;
                      }
                      
                          void *p;
                          while ((p = malloc(size)) == 0) {
                              if (用户设置的应对措施函数(size) == 0) {
                                  // 申请内存失败,抛出异常
                                  static const std::bad_alloc nomem;
                                  throw nomem;
                              }
                          }
                          return p;
                      }
                      
                          if (pUserData == NULL)
                              return;
                          free(pUserData);
                      }
                      
                          // 分配一块原始内存
                          char* rawMemory = new char[sizeof(int)];
                          // 使用定位new在原始内存上构造一个int对象
                          int* intPtr = new (rawMemory) int(42);
                          // 输出构造的int对象的值
                          std::cout 
                      public:
                          MyClass(int value) : data(value) {
                              std::cout 
                              std::cout 
                          // 分配一块原始内存
                          char* rawMemory = new char[sizeof(MyClass)];
                          // 使用定位new在原始内存上构造一个MyClass对象
                          MyClass* myObjPtr = new (rawMemory) MyClass(10);
                          // 显式调用析构函数
                          myObjPtr-~MyClass();
                          // 释放原始内存
                          delete[] rawMemory;
                          return 0;
                      }    
                        // 必须判空!
                          // 处理内存不足的情况
                      }
                      
                          int* p = new int;  // 失败会抛异常,不会返回 NULL
                      } catch (std::bad_alloc& e) {
                          // 处理异常
                      }
                      
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

相关阅读

目录[+]

取消
微信二维码
微信二维码
支付宝二维码