当前位置: 首页 > news >正文

逻辑之舞:C++ 内存分配与释放,在程序的舞台上,演绎着资源的分配与回收

目录

一、基本概念

二、运行方式

三、深度剖析

1. 内存分配

2. 内存释放

3. RAII(资源获取即初始化)

四、代码示例

五、易错提示

六、总结


一、基本概念

C++ 的内存管理主要涉及以下几个方面:

  • 内存模型 C++ 采用的是堆栈模型,主要包括以下几个区域:

    • 栈区(Stack) 用于存放局部变量、函数参数、返回值等数据,具有先进后出的特点。

    • 堆区(Heap) 用于存放动态分配的内存,可以根据需要进行分配和释放,具有灵活性的特点。

    • 全局/静态区(Global/Static) 用于存放全局变量、静态变量等数据,在程序启动时分配,在程序结束时释放。

    • 常量区(Constant) 用于存放常量数据,一般在程序编译时分配。

    • 代码区(Code) 用于存放程序代码。

  • 内存分配 C++ 提供了以下几种内存分配方式:

    • 静态分配 在编译时分配内存,例如全局变量、静态变量。

    • 动态分配 在运行时分配内存,使用 new 和 malloc 等函数。

  • 内存释放 C++ 提供了以下几种内存释放方式:

    • 自动释放 栈区中的内存由系统自动释放,无需手动释放。

    • 手动释放 堆区中的内存需要手动释放,使用 delete 和 free 等函数。

二、运行方式

  • 栈区 栈区内存由编译器自动管理,在函数调用时分配,函数调用结束后自动释放。

  • 堆区 堆区内存由程序员手动管理,使用 new 或 malloc 函数分配内存,使用 delete 或 free 函数释放内存。

  • 内存泄漏 如果程序员忘记释放堆区中的内存,会导致内存泄漏,最终导致系统崩溃。

  • 悬挂指针 如果释放了指向堆区内存的指针,但该内存仍然被其他指针引用,会导致悬挂指针,访问悬挂指针会导致程序崩溃。

三、深度剖析

1. 内存分配

  • new 和 malloc

    • new 是 C++ 的关键字,用于在堆区分配内存,并返回指向分配内存的指针。

    • malloc 是 C 语言库函数,也用于在堆区分配内存,但返回的是 void* 类型指针,需要进行类型转换。

  • 内存分配器 C++ 使用内存分配器来管理堆区的内存,常用的内存分配器有 std::allocatorstd::operator new等。

  • 内存池 为了提高内存分配的效率,可以采用内存池技术,预先分配一块较大的内存区域,然后将该区域划分为多个大小不同的内存块,当需要分配内存时,直接从内存池中获取即可,避免频繁调用系统函数。

2. 内存释放

  • delete 和 free

    • delete 用于释放由 new 分配的内存。

    • free 用于释放由 malloc 分配的内存。

  • 内存释放顺序 释放内存时,需要按照分配顺序进行释放,否则会导致内存泄漏或其他错误。

3. RAII(资源获取即初始化)

  • RAII 原则 RAII 是一种 C++ 内存管理技术,它将资源的获取和释放与对象的构造和析构函数绑定在一起。

  • 实现方式 使用类来封装资源,在构造函数中获取资源,在析构函数中释放资源。

  • 优点 RAII 可以确保资源在对象的生命周期内得到正确的管理,避免内存泄漏和悬挂指针。

四、代码示例

#include <iostream>class MyClass 
{
public:MyClass() {data = new int[10]; // 在构造函数中分配内存std::cout << "MyClass object created." << std::endl;}~MyClass() {delete[] data; // 在析构函数中释放内存std::cout << "MyClass object destroyed." << std::endl;}void printData() {for (int i = 0; i < 10; i++) {std::cout << data[i] << " ";}std::cout << std::endl;}private:int* data;
};int main() 
{MyClass obj; // 创建 MyClass 对象,自动调用构造函数分配内存obj.printData();// 对象超出作用域,自动调用析构函数释放内存return 0;
}

五、易错提示

  • 内存泄漏 忘记释放堆区中的内存,会导致内存泄漏。

  • 悬挂指针 释放了指向堆区内存的指针,但该内存仍然被其他指针引用,会导致悬挂指针。

  • 双重释放 对同一块内存进行多次释放,会导致程序崩溃。

  • 越界访问 访问超出分配内存范围的地址,会导致程序崩溃。

六、总结

        C++ 内存管理是一个复杂的话题,需要程序员仔细理解和掌握。正确使用内存分配和释放机制,可以避免内存泄漏和悬挂指针,提高程序的健壮性和可靠性。RAII 技术可以有效地简化内存管理,提高代码的安全性。


http://www.mrgr.cn/news/53904.html

相关文章:

  • 可编辑PPT | 生产及质量BI应用场景方案
  • 刷爆Leetcode Day4
  • 暴雨亮相第四届岩土力学与工程青年科学家论坛
  • 高等数学 7.5可降阶的高阶微分方程
  • Resources的资源加载管理器
  • 使用 Docker-compose 部署达梦 DM 数据库
  • 解决SolidWorks装配体无法更改透明度问题
  • 【数据结构】栈
  • 数仓建设:如何设计数据治理考评规则?
  • 类和对象(中)后面部分
  • 【note】GNN
  • Dropout为何能防止过拟合?dropout和BN 在前向传播和方向传播阶段的区别?
  • 「图::连通」详解并查集并实现对应的功能 / 手撕数据结构(C++)
  • 挑战自闭症儿童康复:探索有效治疗方法
  • C#从零开始学习(类型和引用)(4)
  • 解锁C++多态的魔力:灵活与高效的编码艺术(下)
  • 每日一题——第一百一十七题
  • 【部署篇】rabbitmq-01介绍
  • 【openGauss】OPENGAUSS/POSTGRESQL 中float类型到int类型的隐式转换
  • 直播带货APP开发指南:基于多商户商城系统源码的方案实战
  • vscode 预览markdown 文件
  • 竹壳天气时钟(三)TFT屏幕显示中文
  • 量价关系总结
  • Redis入门到精通(二):入门Redis看这一篇就够了
  • AI动漫翻唱项目玩法拆解,起号涨粉咔咔猛,实操干货分享
  • ICMP协议以及ARP欺骗攻击