C/C++ - 内存管理(C++)

堆栈

  • C++中的栈和堆是用于存储变量和对象​​的两个主要内存区域。
  • 栈是一种自动分配和释放内存的区域,用于存储局部变量和函数调用的上下文。栈上的内存分配和释放是自动进行的,无需手动管理。
  • 堆是动态分配内存的区域,用于存储动态创建的对象和数据结构。
  • 堆上的内存分配和释放需要手动进行,通过使用 new / malloc​​ 和 delete / free​​ 运算符或者使用智能指针等机制。
  • 堆(Heap)

    • 堆是在程序运行时动态分配内存的区域,用于存储动态创建的对象和数据结构。

    • 在堆上分配的内存需要手动进行管理,通过使用 new​​​ 和 delete​​​ 运算符或者智能指针​​等机制进行内存的分配和释放。

    • 堆上的内存可以在任何时候进行分配和释放,而不受作用域的限制。

      int* ptr = new int;  // 动态分配一个整型内存块
      *ptr = 5;
      delete ptr;  // 释放内存
      
  • 栈(tack)

    • 栈是基于线程而言的,每条线程都有属于自己的栈区。

    • 栈是一种自动分配和释放内存的区域,用于存储局部变量和函数调用的上下文。

    • 栈上的内存分配和释放是自动进行的,无需手动管理。

    • 栈上的内存分配和释放遵循“先进后出”的原则,即最后进入栈的变量最先离开。

      void foo() 
      {int x = 5;  // 在栈上分配整型变量// ...
      }  // 函数结束,栈上的变量自动释放
      
  • 栈上分配的内存特点

    • 栈上分配的内存空间相对较小,受限于编译器和操作系统的设置。通常在几兆字节到几十兆字节之间。
    • 栈上的内存分配和释放速度较快,仅涉及移动栈指针。
    • 栈上的内存分配是按照严格的顺序进行的,无法随机访问。
  • 堆和栈的比较

    • 堆和栈都是用于存储数据的内存区域,但它们有不同的特点和用途。
    • 堆适用于动态分配内存,可以在任何时候进行分配和释放,适用于需要灵活管理内存的情况。
    • 栈适用于自动分配和释放内存,适用于局部变量和函数调用的上下文。

内存

  • new

    • 动态分配单个对象

      • 使用new​​​​运算符可以在堆上动态分配单个对象的内存,并返回指向该内存的指针。

      • 语法:new 类名;​​​​ 或 new 类名(参数);​​​​

        int* ptr = new int;  // 动态分配一个整型对象
        *ptr = 5;  // 对分配的内存进行操作
        delete ptr;  // 释放内存
        
    • 底层执行

    • 动态分配对象数组:

      • 使用new​​​​运算符可以在堆上动态分配对象数组的内存,并返回指向该内存的指针。

      • 语法:new 类名[数组大小];​​​​

        int* arr = new int[5];  // 动态分配一个包含5个整型元素的数组
        for (int i = 0; i < 5; ++i) 
        {arr[i] = i;
        }
        delete[] arr;  // 释放内存
        
  • delete

    • 释放单个对象内存:

      • 使用delete​​运算符可以释放通过new​​运算符分配的单个对象的内存。

      • 语法:delete 指针;​​

        int* ptr = new int;  // 动态分配一个整型对象
        *ptr = 5;
        delete ptr;  // 释放内存
        
    • 释放对象数组内存:

      • 使用delete[]​​运算符可以释放通过new​​运算符分配的对象数组的内存。

      • 语法:delete[] 指针;​​

        #include <iostream>int main()
        {//new    - malloc//delete - free//Cint* p1 = (int*)malloc(sizeof(int));if (p1){free(p1);p1 = NULL;}int* p2 = (int*)malloc(sizeof(int) * 10);if (p2){free(p2);p2 = NULL;}//CPPint* p3 = new int;if (p3){delete p3;p3 = NULL;}int* p4 = new int(10);if (p4){delete p4;p4 = NULL;}int* p5 = new int[10];if (p5){delete[] p5;p5 = NULL;}return 0;
        }
        
  • 内存失败处理

    • 在使用new​​运算符分配内存时,如果内存不足或分配失败,会抛出std::bad_alloc​​异常。因此,需要在代码中适当处理异常情况

    • 可以使用try-catch​​语句块来捕获并处理异常。

      #include <iostream>void Exception_CPP()
      {try{//可能会出现错误的代码long long* p = new long long[0xFFFFFFF];delete[] p;}catch (const std::exception& Error){//出现异常捕获处理异常std::cout << "Exception ->" << Error.what() << std::endl;}}int main()
      {Exception_CPP();return 0;
      }
      

智能指针

  • 在C++中,智能指针是一种用于管理动态分配的内存资源的工具。它们以对象的形式封装了原始指针,并提供了自动化的内存管理和资源释放,从而减少内存泄漏和悬挂指针等问题。
  • 智能指针主要有两种类型:shared_ptr​​和unique_ptr​​。
  • ​shared_ptr

    • ​shared_ptr​​是一种引用计数智能指针,用于多个指针共享同一个对象。它会跟踪有多少个shared_ptr​​指向同一块内存,并在不再需要时自动释放该内存。

    • 创建

      • std::shared_ptr<int> ptr = std::make_shared<int>(42);
        
    • 引用计数

      • std::shared_ptr<int> ptr1 = std::make_shared<int>(42);
        std::shared_ptr<int> ptr2 = ptr1; // 引用计数递增std::cout << ptr1.use_count() << std::endl; // 输出2,引用计数为2
        
    • 解引用

      • std::shared_ptr<int> ptr = std::make_shared<int>(42);
        std::cout << *ptr << std::endl; // 输出42
        
    • 重置指针

      • std::shared_ptr<int> ptr = std::make_shared<int>(42);
        ptr.reset(); // 释放资源,引用计数减少if (ptr == nullptr) {std::cout << "智能指针为空" << std::endl;
        }
        
  • ​​unique_ptr

    • ​​unique_ptr​​是一种独占式智能指针,用于唯一地拥有一个对象。它提供了对动态分配的内存的所有权,并在不再需要时自动释放该内存。

    • 创建

      • std::unique_ptr<int> ptr = std::make_unique<int>(42);
        
    • ​​移动语义​

      • std::unique_ptr<int> ptr1 = std::make_unique<int>(42);
        std::unique_ptr<int> ptr2 = std::move(ptr1); // 移动语义,ptr1不再拥有资源if (ptr1 == nullptr) 
        {std::cout << "ptr1不再拥有资源" << std::endl;
        }
        
    • 解引用

      • std::unique_ptr<int> ptr = std::make_unique<int>(42);
        std::cout << *ptr << std::endl; // 输出42
        
    • 释放资源

      • std::unique_ptr<int> ptr = std::make_unique<int>(42);
        ptr.release(); // 释放资源,但不销毁指针if (ptr == nullptr) 
        {std::cout << "unique_ptr已释放资源" << std::endl;
        }
        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/654845.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【UE 材质】闪电材质

效果 步骤 1. 新建一个材质这里命名为“M_Lighting” 打开“M_Lighting”&#xff0c;设置混合模式为半透明&#xff0c;着色模型为无光照 在材质图表中添加如下节点 其中&#xff0c;纹理采样节点的纹理是一个线条 此时预览窗口中效果如文章开头所示。

wordpress找不回密码怎么办?4种方法设置新密码

有些WordPress站长太久不登录后台了&#xff0c;所以就忘记了管理员登录密码&#xff0c;这种情况我们应该怎么找回密码呢&#xff1f;或者设置一个新密码呢&#xff1f;下面boke112百科就跟大家分享4种方法设置WordPress新密码。 方法一、登录页面的“忘记密码&#xff1f;”…

基于DistFlow潮流的配电网故障重构MATLAB程序

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 简介 程序采用适用于辐射状网络的DistFlow潮流模型&#xff0c;可输入任意故障线路编号&#xff0c;得到优化重构结果。程序加入了辐射状和连续状约束&#xff0c;保证网络连通性和辐射性&#xff0c;改换成…

85 C++对象模型探索。数据语义学 - 继承多个类,且是虚基类的数据内存模型分析。虚基类表,虚基类表指针

前面我们分析了 继承多个类的情况。上一次分析的这样的情况&#xff1a; 今天看虚基类。先复习一下虚基类&#xff1a;类似下面这样的图 复习虚基类可以解决的问题&#xff1a; 在这之前先要复习一下多继承同一个爷爷类时带来的问题 空间问题 效率问题 二义性问题 //虚基类问…

【一】esp32芯片开发板环境搭建

1、esp32的源码在github上的地址 不同的芯片支持的源码版本不一样&#xff0c;需要根据自己的实际的esp32开发板的芯片下载不用版本的代码 esp32支持多种开发方式&#xff0c;如arduino&#xff0c;ESP-IDF等。官方推荐使用idf开发&#xff0c;ESP-IDF 是乐鑫官方推出的物联网开…

有趣的css - 第一个字符串自动生成文字图标

在设计 app 界面的时候&#xff0c;要展示一部分最新的资讯入口&#xff0c;然后出了一张下面的 UI 稿。 UI稿截图如下&#xff1a; 列表设计比较简单&#xff0c;就是列表前面的圆形图标这块&#xff0c;我个人觉得还是有点意思的。 一般的话&#xff0c;大概率都是用js限制…

【Web前端实操16】雪碧图(CSS精灵图)

雪碧图 CSS Sprite也叫CSS精灵图、CSS雪碧图&#xff0c;是一种网页图片应用处理方式。它允许你将一个页面涉及到的所有零星图片都包含到一张大图中去 雪碧图一般会给一个完整的图片&#xff0c;主要利用background-position 属性设置背景图像的起始位置。 优点 减少图片的字…

单调队列优化DP模型整理

135. 最大子序和&#xff08;活动 - AcWing&#xff09; 找一个长度不超过m的连续子序列&#xff0c;但是并未指定这个子序列的长度&#xff0c;所以长度就有很多种选择&#xff0c;要获取任意一段长度的序列的区间和&#xff0c;那么显然要用到前缀和。然后我们来考虑&#xf…

基于Spring Boot的饮食分享平台设计与实现

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

【Javaweb程序设计】【C00161】基于SSM电子产品交易管理系统(论文+PPT)

基于SSM电子产品交易管理系统&#xff08;论文PPT&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于ssm的电子产品交易系统 本系统分为前台用户和后台管理员2个功能模块. 前台用户模块&#xff1a;当游客打开系统的网址后&#xff0c;首先看到的就…

换个思路快速上手UML和plantUML——时序图

上一章我们介绍了类图&#xff0c;我们很清楚&#xff0c;类图是从更加宏观的角度去梳理系统结构的&#xff0c;从类图中我们可以获取到类与类之间&#xff1a;继承&#xff0c;实现等关系信息&#xff0c;是宏观逻辑。下面我们继续换一个思路&#xff1a;作为一名软件工程结构…

给刚上小学的侄女准备新年礼物,有什么让小朋友喜欢的玩具推荐?

给刚上小学的侄女准备新年礼物&#xff0c;我觉得也是有很多选择的。因为现在的市场上款式太多了&#xff0c;选择自己心意的适合小侄女的都是可以的。但是如果非要选益智的或是智能高科技的&#xff0c;对孩子来说既能玩耍又能在玩的同时学习到知识&#xff0c;能够开拓孩子眼…

无限可能!安全狗入选“潜力十强企业”

近日&#xff0c;等级保护测评公布了“2023年网络安全优秀评选”活动评选结果。 作为国内云原生安全领导厂商&#xff0c;安全狗凭借突出的综合实力&#xff0c;荣获“潜力十强企业”称号。 厦门服云信息科技有限公司&#xff08;品牌名&#xff1a;安全狗&#xff09;创办于20…

《HTML 简易速速上手小册》第10章:HTML 的维护与优化(2024 最新版)

文章目录 10.1 网页性能优化10.1.1 基础知识10.1.2 案例 1&#xff1a;优化网页图像10.1.3 案例 2&#xff1a;使用延迟加载优化性能10.1.4 案例 3&#xff1a;优化 CSS 和 JavaScript 的加载 10.2 SEO 最佳实践10.2.1 基础知识10.2.2 案例 1&#xff1a;创建一个 SEO 友好的博…

数据库管理-第139期 做大还是做小-Oracle名称哪些事(20240125)

数据库管理139期 2024-01-25 第139期 做大还是做小-Oracle名称哪些事&#xff08;20240125&#xff09;1 问题2 排查3 扩展总结 第139期 做大还是做小-Oracle名称哪些事&#xff08;20240125&#xff09; 作者&#xff1a;胖头鱼的鱼缸&#xff08;尹海文&#xff09; Oracle A…

麒麟系统—— openKylin 安装 mongodb

麒麟系统—— openKylin 安装 mongodb 一、准备工作1. 确保麒麟系统 openKylin 已经安装完毕。 二、下载解压 MongoDB二、增加环境变量三、配置MongoDB创建数据目录创建日志文件运行 四、加入到服务中 MongoDB是一款高性能、开源的NoSQL数据库&#xff0c;因其灵活的数据结构、…

MyBatis 的注解实现方法

MyBatis 的注解实现方法 MyBatis 的注解实现方法引入依赖添加配置创建表创建实体类创建mapper接口InsertDeleteSelectResults和ResultMap通过配置文件解决 UpdateOptions MyBatis 的注解实现方法 引入依赖 在springBoot项目中下载了EditStarters插件的,可以直接在配置文件处右…

效率高的B树系列

文章目录 前言B树概念性质插入数据分析代码实现性能分析 B树概念特性插入数据分析应用 B*树概念B*树的分裂 总结B树系列的区别B树系列对比哈希和平衡搜索树 前言 前面我们所学习到的数据结构&#xff0c;只能用来存储少量的数据&#xff0c;因为内存大小是非常有限的&#xff…

.ui文件相关

目录 ui类生成过程&#xff1a; 提问&#xff1a; 等以后自己熟练了用代码写这些样式内容&#xff0c;尽量用代码写&#xff0c;原因很简单&#xff1a; 用代码写的可以直接修改代码&#xff0c;但是在设计界面修改的东西&#xff0c;电脑没有QC这玩意&#xff0c;还真不好改…