c++中的动态内存管理

目录

1.内存分布

2.c语言动态内存管理

3.c++动态内存管理

4.operator new 与operator delete 函数

5.定位new

6.malloc/free 与 new/delete 的区别


1.内存分布

首先我们需要了解一下数据在内存中的分布,请看以下代码:

int globalVar = 1;
static int staticGlobalVar = 1;void Test()
{static int staticVar = 1;int localVar = 1;int num1[10] = { 1, 2, 3, 4 };char char2[] = "abcd";const char* pChar3 = "abcd";int* ptr1 = (int*)malloc(sizeof(int) * 4);int* ptr2 = (int*)calloc(4, sizeof(int));int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);free(ptr1);free(ptr3);
}

【说明】
  • 1. 又叫堆栈--非静态局部变量/函数参数/返回值等等,栈是向下增长的。
  • 2. 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信。(Linux课程如果没学到这块,现在只需要了解一下)
  • 3. 用于程序运行时动态内存分配,堆是可以上增长的。
  • 4. 数据段--存储全局数据和静态数据。
  • 5. 代码段--可执行的代码/只读常量。

2.c语言动态内存管理

c语言动态内存管理:

malloc / calloc / realloc / free :详情可参考c语言动态内存管理函数

面试题:

1. malloc/calloc/realloc 的区别?
答:malloc 与 calloc 都是申请内存空间,只不过calloc 会对空间进行初始化,而 realloc 是对已有空间进行扩展。


3.c++动态内存管理

        C 语言内存管理方式在 C++ 中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因此C++ 又提出了自己的内存管理方式: 通过 new delete 操作符进行动态内存管理
  • new/delete操作内置类型
void Test()
{// 动态申请一个int类型的空间int* ptr4 = new int;// 动态申请一个int类型的空间并初始化为10int* ptr5 = new int(10);// 动态申请10个int类型的空间int* ptr6 = new int[3];delete ptr4;delete ptr5;delete[] ptr6;
}

         注意:申请和释放单个元素的空间,使用 new delete 操作符,申请和释放连续的空间,使用 new[ ] delete[ ] ,注意:匹配起来使用。

  • newdelete操作自定义类型
class A
{
public:A(int a = 0): _a(a){cout << "A():" << this << endl;}~A(){cout << "~A():" << this << endl;}private:int _a;
};int main()
{// new/delete 和 malloc/free最大区别是 new/delete对于【自定义类型】除了开空间还会调用构造函数和析构函数A* p1 = (A*)malloc(sizeof(A));A* p2 = new A(1);free(p1);delete p2;// 内置类型是几乎是一样的int* p3 = (int*)malloc(sizeof(int)); // Cint* p4 = new int;free(p3);delete p4;A* p5 = (A*)malloc(sizeof(A)*10);A* p6 = new A[10];free(p5);delete[] p6;return 0;
}
      注意:在申请自定义类型的空间时, new 会调用构造函数, delete 会调用析构函数,而 malloc free 不会

4.operator new 与operator delete 函数

       new delete 是用户进行 动态内存申请和释放的操作符 operator new operator delete 是 系统提供的全局函数 new 在底层调用 operator new 全局函数来申请空间, delete 在底层通过 operator delete 全局函数来释放空间。
总结:new 的底层是operator new ,operator new 是 malloc 的封装
          delete 的底层是operator delete ,operator delete 是 free 的封装
new delete 的实现原理
内置类型
如果申请的是内置类型的空间, new malloc delete free 基本类似,不同的地方是:new/delete申请和释放的是单个元素的空间, new[] delete[] 申请的是连续空间,而且 new 在申请空间失败时会抛异常,malloc 会返回 NULL
自定义类型
  • 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 来释放空间

 

5.定位new

定位 new 表达式是在 已分配的原始内存空间中调用构造函数初始化一个对象
使用场景:
定位 new 表达式在实际中一般是配合内存池使用。因为内存池分配出的内存没有初始化,所以如果是自定义类型的对象,需要使用new 的定义表达式进行显示调构造函数进行初始化。
class A
{
public:A(int a = 0): _a(a){cout << "A():" << this << endl;}~A(){cout << "~A():" << this << endl;}
private:int _a;
};// 定位new/replacement new
int main()
{// p1现在指向的只不过是与A对象相同大小的一段空间,还不能算是一个对象,因为构造函数没有执行A* p1 = (A*)malloc(sizeof(A));new(p1)A;  // 注意:如果A类的构造函数有参数时,此处需要传参p1->~A();free(p1);A* p2 = (A*)operator new(sizeof(A));new(p2)A(10);p2->~A();operator delete(p2);return 0;
}


6.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 在释放空间前会调用析构函数完成空间中资源的清理

例:


注:概念性内容引自比特科技

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

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

相关文章

2023年全球接口IP市场发展趋势分析:市占率第二IP品类,受大数据及计算需求推动高速增长[图]

接口IP是基于标准接口协议&#xff0c;实现芯片与内外部设备进行通信、传输数据的电路模块&#xff0c;分为有线接口IP与无线接口IP&#xff0c;主要用于数字信号处理和嵌入式系统中的接口设计。 接口IP分类 资料来源&#xff1a;共研产业咨询&#xff08;共研网&#xff09; …

计算机视觉——飞桨深度学习实战-深度学习网络模型

深度学习网络模型的整体架构主要数据集、模型组网以及学习优化过程三部分&#xff0c;本章主要围绕着深度学习网络模型的算法架构、常见模型展开了详细介绍&#xff0c;从经典的深度学习网络模型以CNN、RNN为代表&#xff0c;到为了解决显存不足、实时性不够等问题的轻量化网络…

【LeetCode热题100】--226.翻转二叉树

226.翻转二叉树 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) {* …

TouchGFX之后端通信

在大多数应用中&#xff0c;UI需以某种方式连接到系统的其余部分&#xff0c;并发送和接收数据。 它可能会与硬件外设&#xff08;传感器数据、模数转换和串行通信等&#xff09;或其他软件模块进行交互通讯。 Model类​ 所有TouchGFX应用都有Model类&#xff0c;Model类除了存…

苹果ios系统ipa文件企业签名是什么?优势是什么?什么场合需要应用到?

企业签名是苹果开发者计划中的一种签名类型&#xff0c;允许企业开发者签署和分发企业内部使用的应用程序&#xff0c;而无需通过App Store进行公开发布。通过企业签名&#xff0c;企业可以在内部部署自己的应用程序&#xff0c;以满足特定的业务需求。 企业签名能够做到以下…

搭建自己的搜索引擎之五

一、前言 接上文 搭建自己的搜索引擎之四&#xff0c;下面继续介绍茴香豆茴字的另外两种写法。 二、Jest Jest是ES的Java Http Rest客户端&#xff0c;它主要是为了弥补以前ES自有API缺少HttpRest接口客户端的不足&#xff0c;但因为现在ES官方已经提供了RestClient ,该项目已…

数据结构和算法

数据结构&#xff1a; 线性结构&#xff1a; 顺序存储方式&#xff0c;顺序表 常见的顺序存储结构有&#xff1a;数组、队列、链表、栈 链式存储方式&#xff0c;链表 非线性结构&#xff1a; 常见的非线性结构有&#xff1a;二维数组、多维数组、广义表、树结构、图结构 实…

Nginx 通过A域名代理B域名,保持A域名访问状态

在某些业务场景中需要一种代理方式&#xff0c;就是隐藏某个域名使用另一个域名去代理被需要隐藏的域名&#xff0c;在别人抓包或者别人查看访问地址的时候&#xff0c;看的域名都不是真实域名地址。所以需要用到这种代理方式。 需要被代理的B域名和地址&#xff1a; https:/…

基于Redis实现消息队列的实践

为什么要基于Redis实现消费队列&#xff1f; 消息队列是一种典型的发布/订阅模式&#xff0c;是专门为异步化应用和分布式系统设计的&#xff0c;具有高性能、稳定性及可伸缩性的特点&#xff0c;是开发分布式系统和应用系统必备的技术之一。目前&#xff0c;针对不同的业务场…

【计算机】CPU,芯片以及操作系统概述

1.CPU 什么是CPU? CPU&#xff08;Central Processing Unit&#xff09;是计算机系统的运算和控制核心&#xff0c;是信息处理、程序运行的最终执行单元&#xff0c;相当于系统的“大脑”。 CPU的工作流程&#xff1f; CPU 的工作流程分为以下 5 个阶段&#xff1a;取指令…

时序分解 | Matlab实现CEEMD互补集合经验模态分解时间序列信号分解

时序分解 | Matlab实现CEEMD互补集合经验模态分解时间序列信号分解 目录 时序分解 | Matlab实现CEEMD互补集合经验模态分解时间序列信号分解效果一览基本介绍程序设计参考资料 效果一览 基本介绍 Matlab实现CEEMD互补集合经验模态分解时间序列信号分解 1.分解效果图 &#xff0…

Maven - MacOS 快速安装

配置信息 Maven 版本&#xff1a;3.6.3Maven 地址&#xff1a;Index of /dist/maven/maven-3IDEA&#xff1a;2023 Tips&#xff1a;Maven 版本最好不要超过 3.8.0&#xff0c;最新版 Maven 会不兼容一些配置信息。上面的 Maven 地址里可以选择自己想下载的版本&#xff08;这…

SpringBoot中使用拦截器

拦截器属于MVC中的内容 SpringBoot项目,引入web依赖即可 需要访问的控制器 拦截器第一步实现HandlerInterceptor接口 第二步实现WebMvcConfigurer接口,并重写addInterCeptors()方法,将自定义的拦截器注册 也就是说这里add进去拦截的请求,才会进入到prehandle方法,这里放行的请…

iOS UWB——Neaby Interaction框架(一)

苹果自2019年在iPhone中引入UWB技术&#xff0c;伴随着的就是其应用软件框架Nearby Interaction框架的升级。Nearby Interaction框架&#xff0c;是一个功能强大且易于使用的iOS空间感知能力。通过NI框架&#xff0c;支持开发者和配件制造商将对象检测和设备激活等功能整合到应…

rust生命期

一、生命期是什么 生命期&#xff0c;又叫生存期&#xff0c;就是变量的有效期。 实例1 {let r;{let x 5;r &x;}println!("r: {}", r); }编译错误&#xff0c;原因是r所引用的值已经被释放。 上图中的绿色范围’a表示r的生命期&#xff0c;蓝色范围’b表示…

Koa处理请求数据

在开发中&#xff0c;后端接收到请求参数后&#xff0c;需要解析参数。请求分为很多种类型&#xff0c;比如常见的get和post。 请求参数 Koa本身可以解析get请求参数&#xff0c;不能解析post请求参数。例如&#xff1a; router.get(/api/get/userInfo, async (context) >…

计算机网络(四):网络层

参考引用 计算机网络微课堂-湖科大教书匠计算机网络&#xff08;第7版&#xff09;-谢希仁 1. 网络层概述 网络层的主要任务是实现网络互连&#xff0c;进而实现数据包在各网络之间的传输 要实现网络层任务&#xff0c;需要解决以下主要问题 网络层向运输层提供怎样的服务 (“…

Origin分段显示柱状图

注意这里生成的是柱状图&#xff0c;而不是直方图。因此用到的是plot -> column/bar/pie -> stacked column&#xff1a; 而不是Statistical->histogram。 先上最终的作图效果&#xff1a; 单个柱的柱状图 第一步先填充数据&#xff0c;如图左所示&#xff0c;然后选…

Android shape记录

之前一直觉得dataPath很好用&#xff0c;可以画各种矢量图。今天发现用shape画图也不错&#xff0c;记录一下自己用shape画的图。 一般使用shape就是定义形状、stroke边、solid内部、corners圆角等&#xff0c;代码 <?xml version "1.0" encoding "utf-8&q…

IntelliJ IDEA 常用快捷键

目录 一、IDEA 常用快捷键 1 通用型 2 提高编写速度 3 类结构、查找和查看源码 4 查找、替换与关闭 5 调整格式 二、Debug快捷键 三、查看快捷键 1、已知快捷键操作名&#xff0c;未知快捷键 2、已知快捷键&#xff0c;不知道对应的操作名 3、自定义快捷键 4、使用…