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.rhkb.cn/news/247680.html

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

相关文章

滴滴基于 Ray 的 XGBoost 大规模分布式训练实践

背景介绍 作为机器学习模型的核心代表&#xff0c;XGBoost 在滴滴众多策略算法业务场景中发挥着至关重要的作用。因此&#xff0c;保障并持续提升 XGBoost 模型的离线训练及在线推理稳定性一直是机器学习平台的重点工作。同时&#xff0c;面对多样化的业务场景定制需求和数据规…

go语言(十八)---- goroutine

一、goroutine package mainimport ("fmt""time" )func main() {//用go创建承载一个形参为空&#xff0c;返回值为空的一个函数go func() {defer fmt.Println("A.defer")func() {defer fmt.Println("B.defer")//退出当前goroutinefmt…

Markdown(2篇文章学会Markdown

目录 1.文章链接&#xff1a;2.markdown可以用来解决什么问题&#xff1a;小结&#xff1a; 1.文章链接&#xff1a; Markdown&#xff08;2篇文章学会Markdown第一篇 Markdown&#xff08;2篇文章学会Markdown第二篇 2.markdown可以用来解决什么问题&#xff1a; 格式化文…

C++多线程1(复习向笔记)

创建线程以及相关函数 当用thread类创建线程对象绑定函数后&#xff0c;该线程在主线程执行时就已经自动开始执行了,join起到阻塞主线程的作用 #include <iostream> #include <thread> #include <string> using namespace std; //测试函数 void printStrin…

神经网络建立(结果可变)最小神经元

目录 介绍&#xff1a; 初始化&#xff1a; 建模: 预测&#xff1a; 改变结果&#xff1a; 介绍&#xff1a; 在深度学习中&#xff0c;神经元通常指的是人工神经元&#xff08;或感知器&#xff09;&#xff0c;它是深度神经网络中的基本单元。深度学习的神经元模拟了生…

【服务器GPT+MJ+GPTs】创建部署GPT+MJ+GPTs程序网站

目录 🌺【前言】 🌺【准备】 🌺【宝塔搭建GPT+MJ+GPTs】 🌼1. 给服务器添加端口 🌼2. 安装宝塔 🌼3. 安装Docker 🌼4. 安装ChatGPT程序 🌼5. 程序更新 🌼6. 修改端口 | 密码 🌼7. 绑定域名+申请SSL证书 🌺【前言】 相信大家都对openai的产品ch…

Kafka(九)跨集群数据镜像

目录 1 跨集群镜像的应用场景1.1 区域集群和中心集群1.2 高可用(HA)和灾备(DR)1.3 监管与合规1.4 云迁移1.5 聚合边缘集群的数据 2 多集群架构2.1 星型架构2.2 双活架构2.2 主备架构2.2.1 如何实现Kafka集群的故障转移2.2.1.1 故障转移包括的内容1. 灾难恢复计划2. 非计划内的故…

重写Sylar基于协程的服务器(0、搭建开发环境以及项目框架 || 下载编译简化版Sylar)

重写Sylar基于协程的服务器&#xff08;0、搭建开发环境以及项目框架 || 下载编译简化版Sylar&#xff09; 重写Sylar基于协程的服务器系列&#xff1a; 重写Sylar基于协程的服务器&#xff08;0、搭建开发环境以及项目框架 || 下载编译简化版Sylar&#xff09; 前言 sylar是…

计网Lesson11 - 虚拟机网络环境及socket概述

文章目录 虚拟机的简述socket概述 虚拟机的简述 放张图在这&#xff0c;根本没明白是啥对啥&#xff0c;以后学了Linux再来吧 &#x1f626; socket概述 s o c k e t socket socket 是一种用于应用层的用户态与应用层以下的内核态交互的工具&#xff0c;本意为“插座”。 也就是…

网络协议与攻击模拟_08DHCP协议

技术学习要了解某项技术能干什么&#xff1f;它的详细内容&#xff1f;发展走向&#xff1f; 一、DHCP协议 1、DHCP基本概念 dhcp动态主机配置协议&#xff0c;广泛应用于局域网内部 主要是为客户机提供TCP/IP 参数&#xff08;IP地址、子网掩码、网关、DNS等&#xff09;…

YOLO 全面回顾:从最初的YOLOv1到最新的YOLOv8、YOLO-NAS,以及整合了 Transformers 的 YOLO

YOLO 全面回顾 综述评估指标YOLO v1YOLO v2YOLO v3YOLO v4YOLOv5 与 Scaled-YOLOv4 YOLORYOLOXYOLOv6YOLOv7DAMO-YOLOYOLOv8PP-YOLO, PP-YOLOv2, and PP-YOLOEYOLO-NASYOLO with Transformers 综述 论文&#xff1a;https://arxiv.org/pdf/2304.00501.pdf 代码&#xff1a;gi…

探索设计模式的魅力:深入了解适配器模式-优雅地解决接口不匹配问题

设计模式专栏&#xff1a;http://t.csdnimg.cn/nolNS 目录 一、引言 1. 概述 2. 为什么需要适配器模式 3. 本文的目的和结构 二、简价 1. 适配器模式的定义和特点 定义 特点 2. 适配器模式的作用和适用场景 作用 适用场景 3. 适配器模式与其他设计模式的比较 三、适配…

iOS 面试 Swift基础题

一、Swift 存储属性和计算属性比较&#xff1a; 存储型属性:用于存储一个常量或者变量 计算型属性: 计算性属性不直接存储值,而是用 get / set 来取值 和 赋值,可以操作其他属性的变化. 计算属性可以用于类、结构体和枚举&#xff0c;存储属性只能用于类和结构体。存储属性可…

认识产品经理 一个合格的产品经理 产品经理分类

目录 一.合格的产品经理 什么是产品 什么是产品经理 合格的产品经理 什么是产品&#xff1f;区别是&#xff1f; 什么是产品经理 合格的产品经理需要关注哪些核心问题&#xff1f; 二.产品经理分类 为什么会有不同类型 都有那些类型 根据不同类型的职责特点规划个人…

Mysql-InnoDB-数据落盘

概念 1 什么是脏页&#xff1f; 对于数据库中页的修改操作&#xff0c;则首先修改在缓冲区中的页&#xff0c;缓冲区中的页与磁盘中的页数据不一致&#xff0c;所以称缓冲区中的页为脏页。 2 脏页什么时候写入磁盘&#xff1f; 脏页以一定的频率将脏页刷新到磁盘上。页从缓冲区…

C/C++编码问题研究

文章目录 一、Unicode字符集与U8/U16/U32编码二、编码1. 占字节数2. ASCII、GB2312、GBK、GB18030 以及 UTF8 的关系3. BOM4. UTF-8的存储实现 三、编译器字符集设置1. GCC语法Example 2. MSVC语法Example 三、wchar_t五、编码转换函数六、代码 & 实践1. UTF8与UTF16、UTF3…

PDF标准详解(一)——PDF文档结构

已经很久没有写博客记录自己学到的一些东西了。但是在过去一年的时间中自己确实又学到了一些东西。一直攒着没有系统化成一篇篇的文章&#xff0c;所以今年的博客打算也是以去年学到的一系列内容为主。通过之前Vim系列教程的启发&#xff0c;我发现还是写一些系列文章对自己的帮…

HCIP寒假第8次作业

第一步把ipv4网络配通 [r1]int g0/0/0 [r1-GigabitEthernet0/0/0]ip add 12.1.1.1 24 [r1-GigabitEthernet0/0/0]int l0 [r1-LoopBack0]ip add 1.1.1.1 32 [r1]ospf 1 router-id 1.1.1.1 [r1-ospf-1]area 0 [r1-ospf-1-area-0.0.0.0]network 0.0.0.0 255.255.255.255[r2]int g…

静态分析Golang语言生成函数调用关系的利器——go-callvis

目录 升级go删除旧版本安装新版本配置环境变量载入环境修改当前环境修改之后进入的环境 分析安装go-callvis分析其他包总结 导出文件总结 清晰主体脉络总结 其他 参考资料 不同于之前分析C语言项目的工具&#xff0c;go-callvis还是很方便使用。只要把两项工作做好就能顺利的使…

MySQL 定位长事务(Identify Long Transactions)

在MySQL的运行中&#xff0c;经常会遇到一些长事务。长事务意味着长时间持有系统资源&#xff0c;这在OLAP系统中很常见&#xff0c;但在OLTP系统中&#xff0c;长事务意味着争用、并发降低&#xff0c;等待。长事务伴随的典型现象就是经常听到开发人员说"xxx表被锁住了……