【C++】——内存管理
目录
- 回忆C语言内存管理
- C++内存管理方式new delete
- operator new与operator delete函数
- new和delete的实现原理
- 定位new表达式(placement-new)
- malloc/free和new/delete的区别
回忆C语言内存管理
void Test()
{int* p1 = (int*)malloc(sizeof(int));free(p1);int* p2 = (int*)calloc(4, sizeof(int));//不用freeint* p3 = (int*)realloc(p2, sizeof(int) * 10);free(p3);
}
C++内存管理方式new delete
通过new和delete操作符进行动态内存管理
C++自动计算大小,不需要进行强制类型转换
int main()
{//动态申请一个int型的空间int* p1 = (int*)malloc(sizeof(int));//Cint* p2 = new int;//C++//动态申请10个int型空间int* p3 = (int*)malloc(sizeof(int) * 10);//Cint* p4 = new int[10];//C++free(p1);free(p3);delete p2;delete[] p4;return 0;
}
C++额外支持开空间和初始化
int main()
{int* p1 = new int(10);int* p2 = new int[10] {1, 2, 3};int* p3 = new int[10] {};return 0;
}
malloc没有办法很好的支持动态申请的自定义对象初始化
自定义类型,开空间+调用构造函数初始化
自定义类型,调用析构函数+释放空间
class A
{
public:A(int a = 1){cout << "A(int a = 1)" << endl;}~A(){cout << "~A()" << endl;}
private:int _a;
};
int main()
{//自定义类型,开空间+调用构造函数初始化A* p1 = new A;A* p2 = new A(3);//自定义类型,调用析构函数+释放空间delete p1;delete p2;return 0;
}
int main()
{A aa1(1);A aa2(2);A* p1 = new A[10]{ aa1,aa2 };delete[] p1;A* p2 = new A[10]{ A(1),A(2) };delete[] p2;A* p3 = new A[10]{ 1,2 };delete[] p3;return 0;
}
栈:
typedef int DataType;
class Stack
{
public:Stack(size_t capacity=4){cout << "Stack(size_t capacity)" << endl;_array = new DataType[capacity];_size = 0;_capacity = capacity;}void Push(int x){_array[_size++] = x;}~Stack(){cout << "~Stack()" << endl;delete[] _array;_size = _capacity = 0;}
private:DataType* _array;size_t _size;size_t _capacity;
};
Stack* func()
{int n = 0;cin >> n;Stack* pst = new Stack(n);return pst;
}
int main()
{Stack* ptr = func();ptr->Push(1);ptr->Push(2);delete ptr;return 0;
}
operator new与operator delete函数
new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。
typedef int DataType;
class Stack
{
public:Stack(size_t capacity=4){cout << "Stack(size_t capacity)" << endl;_array = new DataType[capacity];_size = 0;_capacity = capacity;}void Push(int x){_array[_size++] = x;}~Stack(){cout << "~Stack()" << endl;delete[] _array;_size = _capacity = 0;}
private:DataType* _array;size_t _size;size_t _capacity;
};
Stack* func()
{int n = 0;cin >> n;Stack* pst = new Stack(n);return pst;
}
int main()
{Stack* pst1 = (Stack*)operator new(sizeof(Stack));operator delete(pst1);Stack* pst2 = new Stack;delete pst2;return 0;
}
operator new 实际也是通过malloc来申请空间,如果malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施 就继续申请,否则就抛异常。
operator delete 最终是通过free来释放空间的。
new和delete形式要匹配使用
new和delete的实现原理
1、内置类型:
如果申请的是内置类型的空间,new和malloc,delete和free基本类似。不同的地方是:new/delete申请和释放的是单个元素的空间,new[]和delete[]申请的是连续空间,而且new在申请空间失败时会抛异常,malloc会返回NULL。
2、自定义类型:
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来释放空间
定位new表达式(placement-new)
定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象。
使用格式:new (place_address) type或者new (place_address) type(initializer-list)
place_address必须是一个指针,initializer-list是类型的初始化列表
**使用场景:**定位new表达式在实际中一般是配合内存池使用。因为内存池分配出的内存没有初始化,所以如
果是自定义类型的对象,需要使用new的定义表达式进行显示调构造函数进行初始化
typedef int DataType;
class Stack
{
public:Stack(size_t capacity=4){cout << "Stack(size_t capacity)" << endl;_array = new DataType[capacity];_size = 0;_capacity = capacity;}void Push(int x){_array[_size++] = x;}~Stack(){cout << "~Stack()" << endl;delete[] _array;_size = _capacity = 0;}
private:DataType* _array;size_t _size;size_t _capacity;
};
Stack* func()
{int n = 0;cin >> n;Stack* pst = new Stack(n);return pst;
}int main()
{Stack* pst1 = (Stack*)operator new(sizeof(Stack));//pst1->Stack(4);//不支持new(pst1)Stack(4);//显示调用构造函数pst1->~Stack();operator delete(pst1);return 0;
}
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在释放空间前会调用析构函数完成空间中资源的清理
相关文章:

【C++】——内存管理
目录 回忆C语言内存管理C内存管理方式new deleteoperator new与operator delete函数new和delete的实现原理定位new表达式(placement-new)malloc/free和new/delete的区别 回忆C语言内存管理 void Test() {int* p1 (int*)malloc(sizeof(int));free(p1);int* p2 (int*)calloc(4…...

Jmeter录制HTTPS脚本
Jmeter录制HTTPS脚本 文章目录 添加“HTTP代理服务器”设置浏览器代理证书导入存在问题 添加“HTTP代理服务器” 设置浏览器代理 保持端口一致 证书导入 点击一下启动让jmeter自动生成证书,放在bin目录下: 打开jmeter的SSL管理器选择刚刚生成的证书&…...
Linux 的Centos 7 安装 启动 Google Chrome
我之所以在Centos上安装Chrome主要是为了让Web自动化测试工具可以启动Chrome,协助我做一些工作。 参考:centos7 google-chrome的安装与启动 - 简书 1.安装chrome逻辑 1. 下载安装包 2. 安装 3. 启动 》这就是在window上的逻辑,只是用命令行…...

DNS WEB HTTP
DNS与域名 网络是基于 TCP/IP 协议进行通信和连接的。 每一台主机都有唯一的标识,用于区别在网络上成千上万个用户和计算机。即固定的IP地址(32位二进制数转换成为十进制数——点分十进制)。每一个与网络相连接的计算机和服务器都被指派一个…...

微信小程序animation动画,微信小程序animation动画无限循环播放
需求是酱紫的: 页面顶部的喇叭通知,内容不固定,宽度不固定,就是做走马灯(轮播)效果,从左到右的走马灯(轮播),每播放一遍暂停 1500ms ~ 2000ms 刚…...

node.js
什么是Node.js Node.js 是一个免费的、开源的、跨平台的 JavaScript 运行时环境,使开发者可以搭建服务器端的JavaScript应用程序 概念: 使用Node.js编写后端程序 // 支持前端工程化 后端程序:提供接口和数据 ,网页资源 前端工程化:对代码压缩&…...

【微信小程序创作之路】- 小程序远程数据请求、获取个人信息
【微信小程序创作之路】- 小程序远程数据请求、获取个人信息 第七章 小程序远程数据请求、获取个人信息 文章目录 【微信小程序创作之路】- 小程序远程数据请求、获取个人信息前言一、远程数据请求1.本地环境2.正式域名 二、获取用户个人信息1.展示当前用户的身份信息2.获取用…...

XML基础知识讲解
文章目录 1. xml简介2. xml快速入门3. xml的元素(标签)定义4. xml标签的命名规范5. xml的属性定义和注释6. 转义字符7. CDATA区8. xml的处理指令9. xml的约束 1. xml简介 XML(eXtensible Markup Language)是一种用于描述数据的标记语。 它以纯文本的方…...

(十二)大数据实战——hadoop集群之HDFS高可用自动故障转移
前言 本节内容主要介绍一下hadoop集群下实现HDFS高可用的自动故障转移,HDFS高可用的自动故障转移主要通过zookeeper实现故障的监控和主节点的切换。自动故障转移为 HDFS 部署增加了两个新组件:ZooKeeper 和 ZKFailoverController (ZKFC&…...
Ubuntu下载deb包及其依赖包
一、简介 有时我们需要在离线环境使用提前准备好的deb包,然后只需要在新机器使用dpkg -i安装即可。 二、命令 apt-get download $(apt-rdepends (需要下载的包,可以有多个) | grep -v "^ " | sed s/debconf-2.0/debco…...
Ubuntu中解/压缩命令
一、zip文件 #解压 unzip filename.zip #压缩 zip filename.zip dirname # 递归处理,将指定目录下的所有文件和子目录一并压缩 zip -r filename.zip dirname 二、tar文件 # 解压 tar xvf FileName.tar # 压缩,将DirName和其下所有文件(夹)打包非压…...

剑指 Offer 12. 矩阵中的路径(回溯 DFS)
文章目录 题目描述思路分析完整代码 题目描述 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。 单词必须按照字母顺序,通过相邻的单元格内的字母构成ÿ…...
iceberg对比hive优势
1.事务性 从事务性上来说,iceberg具有更高的数据质量。 因为iceberg本质是一种table format,屏蔽了底层的存储细节,写入数据时候需要严格按照schema写入。而hive可以先写入底层数据,然后使用load partition的方式来加载分区。这样…...

ProgressBar基本使用
作用:进度条,用于展示某个任务的完成情况, 常用属性: 设定进度条的最大、最小值、自增步长 常用事件: 后台代码: private void progressBar1_Click(object sender, EventArgs e){Thread t;//使用线程执行…...
spring boot java使用XEasyPdf生成pdf文档
java使用XEasyPdf生成pdf文档 spring boot java使用XEasyPdf生成pdf文档第一步导入maven坐标,pom.xml全部贴上第二步编写代码代码实战: spring boot java使用XEasyPdf生成pdf文档 第一步导入maven坐标,pom.xml全部贴上 <?xml version"1.0" encoding…...

自定义elementui的主题
通常情况下,我们使用elementui框架的时候默认组件的主题都是白色的,比如: 但是如果想自定义主题,改变主题颜色,以及各种默认颜色,其实也不难: 配置默认主题,选好后点击下载 在vu…...

eNSP interface g0/0/0 报错解决办法
文章目录 1 报错截图2 解决办法2.1 排查设备是否有 GM 接口2.2 更换适合的路由器,并验证 1 报错截图 2 解决办法 2.1 排查设备是否有 GM 接口 查看下设备是否支持 GM 接口(GigabitEthernet) 方式一:右键路由器设备 - 设置 - 查看…...

Metric3D:Towards Zero-shot Metric 3D Prediction from A Single Image
参考代码:Metric3D 介绍 在如MiDas、LeReS这些文章中对于来源不同的深度数据集使用归一化深度作为学习目标,则在网络学习的过程中就天然失去了对真实深度和物体尺寸的度量能力。而这篇文章比较明确地指出了影响深度估计尺度变化大的因素就是焦距 f f f…...

k8s ingress获取客户端客户端真实IP
背景 在Kubernetes中,获取客户端真实IP地址是一个常见需求。这是因为在负载均衡架构中,原始请求的源IP地址会被替换成负载均衡器的IP地址。 获取客户端真实IP的需求背景包括以下几点: 安全性:基于客户端IP进行访问控制和认证授…...

Mysql主从搭建 基于DOCKER
创建目录 #主节点目录 mkdir -p /home/data/master/mysql/#从节点目录 mkdir -p /home/data/slave/mysql/创建配置文件 # 主节点配置 touch /home/data/master/mysql/my.cnf# 从节点配置 touch /home/data/slave/mysql/my.cnf编辑配置文件 主节点配置文件 vim /home/data/m…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...

【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

tauri项目,如何在rust端读取电脑环境变量
如果想在前端通过调用来获取环境变量的值,可以通过标准的依赖: std::env::var(name).ok() 想在前端通过调用来获取,可以写一个command函数: #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...

MySQL的pymysql操作
本章是MySQL的最后一章,MySQL到此完结,下一站Hadoop!!! 这章很简单,完整代码在最后,详细讲解之前python课程里面也有,感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...
深入浅出WebGL:在浏览器中解锁3D世界的魔法钥匙
WebGL:在浏览器中解锁3D世界的魔法钥匙 引言:网页的边界正在消失 在数字化浪潮的推动下,网页早已不再是静态信息的展示窗口。如今,我们可以在浏览器中体验逼真的3D游戏、交互式数据可视化、虚拟实验室,甚至沉浸式的V…...