【C/C++】4.C++的内存管理

打印 上一主题 下一主题

主题 860|帖子 860|积分 2580

1. C++内存地区

     C++程序的内存通常分为以下几部分:

  • 栈区(Stack)
    栈用于存储局部变量、函数参数等临时数据。当函数调用时会为局部变量主动分配栈内存,函数结束后会主动开释。栈的内存分配速度很快,但空间有限。
  • 堆区(Heap)
    堆用于动态分配内存。程序员可以在运行时申请内存,当不再利用时手动开释。这种内存管理更灵活,但必要留意内存泄漏的问题。
  • 全局/静态区(Global/Static)
    存储全局变量和静态变量。在程序开始时分配内存,并在程序结束后开释。
  • 代码区(Code)
    用于存放程序的可执行代码。通常只读,以防止程序被意外修改。
2. 内存管理方式

2.1 栈上分配

    栈上的内存分配和开释是主动完成的,不必要程序员手动管理。栈内存用于存储局部变量、函数参数等临时数据。
   void exampleFunction() {     int x = 10;       // x 是栈上的局部变量     int y = 20;       // y 是栈上的局部变量  }  // exampleFunction结束后,x 和 y 的内存会主动开释2.2 堆上分配

    堆上内存分配是动态的,必要程序员手动分配和开释。new运算符用于在堆上分配内存,delete用于开释内存。
   void exampleFunction() {    int* ptr = new int(10);  // 动态分配一个int类型的内存,初始值为10    delete ptr;              // 开释内存  }

  • 动态数组分配: int* array = new int[5];  // 分配一个包含5个整数的数组delete[] array;           // 利用 delete[] 开释数组
留意:

     如果没有及时利用delete开释内存,就会导致内存泄漏(memory leak)。这是由于在程序运行期间,未开释的内存将无法被再次利用。
3. 智能指针(Smart Pointers)

     在当代C++中,智能指针用于简化内存管理,镌汰内存泄漏的风险。C++11提供了几种常见的智能指针:

  • std::unique_ptr
    独占式所有权,体现该对象只有一个所有者,脱离作用域时会主动开释内存。
     #include std::unique_ptr ptr = std::make_unique(10);  // 主动开释内存
  • std::shared_ptr
    共享所有权,可以有多个指针指向同一个对象。当最后一个指向对象的shared_ptr被销毁时,对象的内存才会被开释。
     #include std::shared_ptr ptr1 = std::make_shared(10);std::shared_ptr ptr2 = ptr1;   // ptr1 和 ptr2共享同一个对象
  • std::weak_ptr
    辅助shared_ptr利用,不会增长对象的引用计数,常用于办理shared_ptr循环引用的问题。
     #include std::shared_ptr sharedPtr = std::make_shared(10);std::weak_ptr weakPtr = sharedPtr;  // weakPtr不会影响sharedPtr的引用计数
4. 常见的内存管理问题

4.1 内存泄漏(Memory Leak)

      内存泄漏是指程序在堆上分配了内存,但没有开释,导致内存永久占用。长时间运行的程序(如服务器)如果出现内存泄漏,可能会耗尽系统内存。
      示例:
    void memoryLeakExample() {       int* ptr = new int(10);    // 忘记开释 ptr,导致内存泄漏   }4.2 悬空指针(Dangling Pointer)

      悬空指针指的是指向已经被开释内存的指针,若尝试访问该内存会导致未定义行为。
      示例:
    void danglingPointerExample() {      int* ptr = new int(10);      delete ptr;      // 开释内存      // ptr 现在是悬空指针   }4.3 野指针(Wild Pointer)

      野指针是指未初始化的指针,其指向未知的内存地址,容易导致程序崩溃。
      示例:
    void wildPointerExample() {       int* ptr;        // 未初始化,ptr是野指针       *ptr = 10;       // 可能导致程序崩溃   }5. C++ RAII原则

      RAII(Resource Acquisition Is Initialization,资源获取即初始化)是一种重要的内存管理原则。
      它强调在构造对象时获取资源,并在对象销毁时开释资源。智能指针和标准库容器(如std::vector)都遵照RAII原则,可以主动管理内存的分配和开释,镌汰了手动管理的贫苦。遵照RAII原则可以有用镌汰内存管理的错误,提高程序的安全性和健壮性。
     示例:
   #include   #include   void raiiExample() {     std::vector vec = {1, 2, 3, 4, 5};  // 利用 vector 主动管理内存     // vector 脱离作用域时主动开释内存  }
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

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

本版积分规则

耶耶耶耶耶

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表