C++中的内存管理

news/2024/4/19 0:59:13/文章来源:https://blog.csdn.net/m0_61894055/article/details/129205418

文章目录

  • 前言
  • 1.C++中内存空间的划分
  • 2.C++内存管理方式
    • 1.对内置类型的处理
    • 2.对自定义类型的处理
    • 3.new和delete实现原理
    • 4.定位new
  • 3.总结
    • 1. malloc/free和new/delete的区别
    • 2. 内存泄漏

前言

C++中的内存空间划分和C语言是很像的,基本上区别不大。但是因C++中,引入了类和对象的概念,涉及到内存空间资源申请和释放的时候,C++提供了另一套内存管理的函数,不再是像C语言那样使用malloc free等相关函数了。本文就围绕C++的内存管理进行简单介绍。


1.C++中内存空间的划分

C++的内存划分和C语言基本一致,大致如下图所示。

在这里插入图片描述

为了更好的理解C++中的内存划分我们可以试着分析如下代码中的变量所处的内存位置。

在这里插入图片描述

globalVar在哪里? staticGlobalVar在哪里? staticVar在哪里? localVar在哪里?
num1 在哪里? char2在哪里? * char2在哪里? pChar3在哪里? * pChar3在哪里?ptr1在哪里? * ptr1在哪里?

galobalVar和staticGlobalVar一个是全局变量一个是静态变量,它们处于数据段;staticVar和localVal一个是静态变量一个是函数体内的局部变量,前者处于数据段后者处于栈区;num1和char 2也都是函数题内的局部变量存在于栈区;*char 2是数组名解引用,数组名是首元素地址,所以*char2也是存在于栈区。pChar3是函数体内的局部变量,也是存在于栈区,pChar3解引用后是拿到常量字符串"abcd"的地址,也就是*pChar3是指向常量字符串的,常量字符串存在于代码段,*pChar3就存在于代码段。prt1是也是函数体内的局部变量,也是存在于栈区。*ptr1是指向从堆中申请的空间,所以*prt1是堆区。

sizeof(num1) ?; sizeof(char2) ?; strlen(char2) ? sizeof(pChar3) ?; strlen(pChar3) ?sizeof(ptr1) ?

num1是数组名那求是求数组大小,第1个值为40,第2个值也是求数组大小就是5,因为/0也需要计算。第3个值是求字符串的长度也就是4,第4个值求指针变量的大小也就是4或者8,第5个值求的字符串的长度,因为pChar3是字符串地址,所以值为4,第6个是求指针变量的大小也就是4或者8.以上单位都是字节。


2.C++内存管理方式

C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。

1.对内置类型的处理

在这里插入图片描述

我们看到new 申请空间能进行初始化,delete 和new除了使用方式和malloc free不同外其他的地方好像都差不多。delete new和malloc free最大的不太体现在对自定义类型的处理上


2.对自定义类型的处理

对于自定义类型的处理我们来看看如图所示的代码样例。

在这里插入图片描述

在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与 free不会.对于内置类型的处理基本上没啥区别。可能有人会说直接 free掉申请自定义类型空间不也能正常使用吗?那我们来看看这样的一段代码。

在这里插入图片描述


new的时候我们new[ ]中指定空间个数 delete[ ]的时候为啥不用呢?在vs中new在开空间的时候会多开一个空间用来保存所开空间的个数,delete的时候就会拿到这个数据进行释放。

在这里插入图片描述

3.new和delete实现原理

new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。operator new 实际也是通过malloc来申请空间,如果malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的。这里要着重说明:operator new和operator 不是重载,只是函数名刚好命名成这样。

对于内置类型

申请的是内置类型的空间,new和malloc,delete和free基本类似,不同的地方是:new/delete申请和释放的是单个元素的空间,new[]和delete[]申请的是连续空间,而且new在申请空间失败时会抛异常,malloc会返回NULL。new同时还能进行初始化,malloc做不到这点。

对于自定义类型

new的原理
1· 调用operator new函数申请空间
2. 在申请的空间上执行构造函数,完成对象的构造

delete的原理
1. 在空间上执行析构函数,完成对象中资源的清理工作
2. 调用operator delete函数释放对象的空间

new T[N]的原理
1. 调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对 象空间的申请
2. 在申请的空间上执行N次构造函数
delete[]的原理
1. 在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理
2. 调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释放空间

4.定位new

定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对对象。使用场景: 定位new表达式在实际中一般是配合内存池使用。因为内存池分配出的内存没有初始化,所以如果是自定义类型的对象,需要使用new的定义表达式进行显示调构造函数进行初始化。所谓内存池可以简单理解为一大块存放内存空间的池子,其实malloc的空间都是从内存池申请的,因为频繁的向系统申请空间太麻烦且效率底下,内存池便应运而生。

代码示例

在这里插入图片描述

使用格式:
new (place_address) type或者new (place_address) type(initializer-list);place_address必须是一个指针,initializer-list是类型的初始化列表.但是实际上一般不会用到定位new,了解即可。


3.总结

1. malloc/free和new/delete的区别

malloc/free和new/delete的共同点是:都是从堆上申请空间,并且需要用户手动释放。不同的地
方是:

1. malloc和free是函数,new和delete是操作符
2. malloc申请的空间不会初始化,new可以初始化
3. malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可,如果是多个对象,[]中指定对象个数即可.
4. malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型
5. malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需要捕获异常
6. 申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理

2. 内存泄漏

什么是内存泄漏:内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。内存泄漏的危害:长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现内存泄漏会导致响应越来越慢,最终卡死。我们平时在写代码的时候一定要注意及时释放申请的空间。

以上内容,如有问题欢迎指正,谢谢!

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

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

相关文章

davis2016评估教程

DAVIS 2016是VOS任务中的一个经典的benchmark,但是一些VOT的算法有时候也可以预测mask,所以也会在上面测一测性能,本次就随手记录一下自己评测的过程,有需要的小伙伴可以往下看。 DAVIS 2016数据集官方项目网站:https:…

TCP四次挥手

TCP 四次挥手过程是怎样的? TCP 断开连接是通过四次挥手方式。 双方都可以主动断开连接,断开连接后主机中的「资源」将被释放,四次挥手的过程如下图: 客户端打算关闭连接,此时会发送一个 TCP 首部 FIN 标志位被置为 1…

node报错

记录bug:运行 npx -p storybook/cli sb init 时报错gyp info spawn C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exegyp info spawn args [gyp info spawn args build/binding.sln,gyp info spawn args /nologo,gyp info spawn args…

prometheus + alterManager + 飞书通知,实现服务宕机监控告警;实测可用

架构设计图 最终效果图 项目准备 xml依赖 <!-- 监控相关 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>io.…

消息队列--Kafka

Kafka简介集群部署配置Kafka测试Kafka1.Kafka简介 数据缓冲队列。同时提高了可扩展性。具有峰值处理能力&#xff0c;使用消息队列能够使关键组件顶住突发的访问压力&#xff0c;而不会因为突发的超负荷的请求而完全崩溃。 Kafka是一个分布式、支持分区的&#xff08;partition…

JAVA 8 新特性 Lamdba表达式

Java8 新特性&#xff1a; 1、Lamdba表达式 2、函数式接口 3、方法引用和构造引用 4、Stream API 5、接口中的默认方法和静态方法 6、新时间日期API 7、Optional 8、其他特性 Java8 优势&#xff1a;速度快、代码更少&#xff08;增加了新的语法 Lambda 表达式&#xff09;、强…

Android 架构 MVC MVP MVVM,这一波你应该了然于心

MVC&#xff0c;MVP和MVVM是软件比较常用的三种软件架构&#xff0c;这三种架构的目的都是分离&#xff0c;避免将过多的逻辑全部堆积在一个类中。在Android中&#xff0c;Activity中既有UI的相关处理逻辑&#xff0c;又有数据获取逻辑&#xff0c;从而导致Activity逻辑复杂不单…

Wireshark抓包

Wireshark 1 抓包时间显示格式 2 界面显示列设置 3 protocol协议解析 4 过滤器 tcp.port&#xff1a;TCP端口tcp.dstport&#xff1a;TCP目的端口tcp.srcport&#xff1a;TCP源端口udp.port&#xff1a;UDP端口udp.dstport&#xff1a;UDP目的端口udp.srcport&#xff1a;UDP…

月薪过3W的软件测试工程师,都是怎么做到的?

对任何职业而言&#xff0c;薪资始终都会是众多追求的重要部分。前几年的软件测试行业还是一个风口&#xff0c;随着不断地转行人员以及毕业的大学生疯狂地涌入软件测试行业&#xff0c;目前软件测试行业“缺口”已经基本饱和。当然&#xff0c;我说的是最基础的功能测试的岗位…

良许也成为砖家啦~

大家好&#xff0c;我是良许。 没错&#xff0c;良许成为砖家啦&#xff0c;绝不是口嗨&#xff0c;有图有真相&#xff01; 有人会说&#xff0c;咦&#xff0c;这明明是严宇啊&#xff0c;跟你良许有啥关系&#xff1f; 额。。老读者应该知道良许的来历—— 鄙人真名严宇&a…

Python-datetime、time包常用功能汇总

目录基础知识时间格式有哪些&#xff1f;Python中的时间格式化时间戳datetimedatedatetimetimedeltatime常用获取今天凌晨字符串&#xff1f;将一个时间格式的字符串转为时间戳将一个时间戳转为指定格式的字符串全部代码参考基础知识 时间格式有哪些&#xff1f; 「格林威治标…

最新OpenMVG编译安装与逐命令运行增量式和全局式SfM教程

openmvg是一个轻便的可以逐步运行的SfM开源库&#xff0c;它同时实现了增量式和全局式两种算法。 说明文档地址&#xff1a;https://openmvg.readthedocs.io/en/latest/ github主页地址&#xff1a;https://github.com/openMVG/openMVG 1 编译安装 openmvg的安装比较简单&…

Windows 11 22H2 中文版、英文版 (x64、ARM64) 下载 (updated Feb 2023)

Windows 11, version 22H2&#xff0c;2023 年 2 月 更新 请访问原文链接&#xff1a;https://sysin.org/blog/windows-11/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;www.sysin.org 全新推出 Windows 11 全新 Windows 体验&#x…

论坛项目小程序和h5登录

项目中安装uview出现npm安装uview 直接报错&#xff1a;创建一个package.json配置文件在进行安装。cmd到项目。初始化一个package.json文件&#xff08;vue项目的配置文件&#xff09; npm init --yes 安装uview项目点击关注进入管页面&#xff0c;需要验证用户是否登录查用户是…

Linux学习(8)Linux文件与目录管理

以下内容转载自鸟哥的Linux私房菜 绝对路径与相对路径 绝对路径&#xff1a;路径的写法『一定由根目录 / 写起』&#xff0c;例如&#xff1a; /usr/share/doc 这个目录。相对路径&#xff1a;路径的写法『不是由 / 写起』&#xff0c;例如由 /usr/share/doc 要到 /usr/share…

Java实现在线沟通功能

文章目录1、介绍 和 特点2、整合SpringBoot2.1、导入依赖2.2、websocket 配置类2.3、消息处理类2.4、启动服务2.5、前端代码&#xff1a;张三2.6、前端代码&#xff1a;李四3、效果4、小结1、介绍 和 特点 t-io是基于JVM的网络编程框架&#xff0c;和netty属同类&#xff0c;所…

【LeetCode】剑指 Offer 14- I. 剪绳子 p96 -- Java Version

题目链接&#xff1a;https://leetcode.cn/problems/jian-sheng-zi-lcof/ 1. 题目介绍&#xff08;14- I. 剪绳子&#xff09; 给你一根长度为 n 的绳子&#xff0c;请把绳子剪成整数长度的 m 段&#xff08;m、n都是整数&#xff0c;n>1并且m>1&#xff09;&#xff0c…

计算机网络你都懂了吗

文章目录一、计算机网络的定义简单定义通用定义二、计算机网络通信过程三、什么是网络协议&#xff08;Protocol&#xff09;四、网络协议组成及功能一、计算机网络的定义 简单定义 计算机网络是一些相互连接的、自治的计算机系统的集合。 通用定义 将处于不同位置并具有独…

MySQL简介、M有SQL的存储引擎、表、字段和数据

Java知识点总结&#xff1a;想看的可以从这里进入 目录2、MySQL特性介绍2.1、MySQL简介2.2、存储引擎2.3、表、字段、数据2、MySQL特性介绍 2.1、MySQL简介 MySQL 是一个关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;于2009年被 Oracle 公司收购。它是一种关…

Hive---排序

Hive语法之排序 文章目录Hive语法之排序全局排序&#xff08;Order By&#xff09;升序降序按照别名排序多个列排序每个 Reduce 内部排序&#xff08;Sort By&#xff09;设置 reduce 个数查看设置 reduce 个数分区排序&#xff08;Distribute By&#xff09;设置 reduce 个数簇…