【c++】c++内存管理
目录
- c和c++的内存分布
- 回顾C语言动态管理内存的方式
- malloc
- calloc
- realloc
- free
- C++动态管理内存的方式
- new和delete
- operator new和operator delete
- 定位new
c和c++的内存分布

回顾C语言动态管理内存的方式
malloc
void* malloc (size_t size);
malloc可以在堆上开辟指定内存的空间,参数是要开辟的空间的大小(单位字节),返回开辟好的空间的指针,注意返回的是无类型指针,需要强转一下指针类型,malloc也不会对开辟好的空间进行初始化。
calloc
void* calloc (size_t num, size_t size);
calloc同样是在堆上开辟指定内存的空间,但它要穿两个参数,num是要开辟的单元数,size是一个单元数的尺寸(单位字节),开辟的总空间大小就是num*size。calloc会对开辟的内存进行初始化,calloc同样返回无类型指针,需要强转。realloc的效率略低于malloc。
realloc
void* realloc (void* ptr, size_t size);
realloc可以更改开辟好的空间的大小,ptr给定需要改变的空间的地址,size为更改后的大小。realloc的扩容分为两种情况,原地扩和异地扩,因为开辟的空间要求是连续的,而堆上操作系统管理的内存并不一定就是连续的,当需要调整的空间后面有连续的空间且容纳的下扩容后的空间就直接原地扩容,以上条件不能满足时系统就会在另一边地方开辟size大小的空间,再把ptr上的数据拷贝过来完成拷贝。显然,原地扩的效率大于异地扩。当ptr为空指针时,realloc效果类似于malloc,当size为0时,realloc效果类似于free,但不推荐因此将realloc当malloc和free使用。calloc同样返回无类型指针,需要强转。
free
void free (void* ptr);
free可以释放动态开辟的内存,动态开辟内存后务必释放,不然会内存泄漏,一片空间只能释放一次。
C++动态管理内存的方式
new和delete
new和delete是c++中的关键字,new可以在堆上动态开辟内存并构造对象。delete可以释放new开辟的空间。使用方法如下。
int main()
{int* a = new int;//开空间不初始化int* b = new int(1);//开空间初始化int* c = new int[10];//开10个int类型的空间不初始化int* d = new int[10] {};//开10个int类型的空间初始化为0int* e = new int[10] {0};//开10个int类型的空间初始化为0int* f = new int[10] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};//开10个int类型的空间初始化为想要的数string* g = new string;//开类类型空间不初始化(调用默认构造)string* h = new string("Hello World");//开类类型空间初始化(调用构造)string* i = new string[10];//开10个类类型数组不初始化(调用10次默认构造)string* j = new string[10]{"jiunian"};//开10个类类型数组初始化了第一个(第一个调用构造,其他默认构造)delete a;delete b;//不是数组直接删delete[] c;delete[] d;delete[] e;delete[] f;//是数组delete后面加[]再删,注意此时delete[]为一个整体,delete[]本身为一个操作符。delete g;delete h;//类类型删除会调用析构函数delete[] i;delete[] j;//调用10次析构函数return 0;
}
new和delete与malloc、calloc、realloc、free的区别是:
1.new和delete是操作符,而malloc、calloc、realloc、free是函数。
2.new和delete在创建类类型对象以及销毁时会调用构造和析构函数。
3.new和delete不需要计算类型大小,也不用强转指针类型,malloc、calloc、realloc、free需要。
operator new和operator delete
/*operator new:该函数实际通过malloc来申请空间,当malloc申请空间成功时直接返回;申请空间失败,
尝试执行空
间不足应对措施,如果改应对措施用户设置了,则继续申请,否则抛异常。
*/
void* __CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{// try to allocate size bytesvoid* p;while ((p = malloc(size)) == 0)if (_callnewh(size) == 0){// report no memory// 如果申请内存失败了,这里会抛出bad_alloc 类型异常static const std::bad_alloc nomem;_RAISE(nomem);}return (p);
}
/*
operator delete: 该函数最终是通过free来释放空间的
*/
void operator delete(void* pUserData)
{_CrtMemBlockHeader* pHead;RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));if (pUserData == NULL)return;_mlock(_HEAP_LOCK); /* block other threads */__TRY/* get a pointer to memory block header */pHead = pHdr(pUserData);/* verify block type */_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));_free_dbg(pUserData, pHead->nBlockUse);__FINALLY_munlock(_HEAP_LOCK); /* release other threads */__END_TRY_FINALLYreturn;
}
/*
free的实现
*/
#define free(p) _free_dbg(p, _NORMAL_BLOCK)
operator new和operator delete是系统提供的全局函数,用来开辟内存空间。操作符new的底层就是通过operator new来申请空间的,操作符delete的底层就是通过operator delete来释放空间的。需要注意的是,operator new和operator delete仍然是通过malloc和free来进行内存的开辟与释放的。另外,需要注意new的作用不只是开辟空间,它还会对空间进行初始化,而delete也不只是释放空间,它还会清空数据。这点在类类型对象的内存开辟时就显得尤为明显,new会调用构造函数,delete会调用析构函数,所以不能简单地将new与operator new、delete与operator delete划等号,他们完全不是一个东西。new与delete是操作符,用法固定;operator new、operator delete是运算符重载函数,可以被重载,自定义成想要的空间开辟方式,如果在全局域或局部域中重载operator new和operator delete(注意重载了operator new就一定要重载对应的operator delete),原来的operator new和operator delete会被覆盖·,此时在这个域中使用new和delete会以自己定义好的方式开辟内存,但在局部域中重载operator new和operator delete可以通过::new、::delete的方式使用原来的operator new和operator delete,所以重载operator new和operator delete的操作建议在局部域中完成,冒然在全局域中重载覆盖原来的operator new和operator delete会然之前写的正常版本的new和delete失效。
定位new
new (address) Type(arguments);
定位new可以在开辟好的内存空间上调用构造函数初始化一个对象,定位new不再会先分配空间再初始化,因为是使用已分配的空间,所以定位new是直接调用构造函数。定位new常被用于内存池管理等方面。具体使用方法如下。
int main()
{std::string* buffer = (std::string*)malloc(sizeof(std::string) * 10);//开辟10个string的空间std::string* obj = new(buffer)std::string("Hello World");//取开头的一个初始化return 0;
}
相关文章:
【c++】c++内存管理
目录 c和c的内存分布回顾C语言动态管理内存的方式malloccallocreallocfree C动态管理内存的方式new和deleteoperator new和operator delete定位new c和c的内存分布 回顾C语言动态管理内存的方式 malloc void* malloc (size_t size);malloc可以在堆上开辟指定内存的空间&#…...
EtherNet/IP转Modbus TCP:新能源风电监控与分析实用案例
EtherNet/IP转Modbus TCP:新能源风电监控与分析实用案例 一、案例背景 在某新能源汽车电池生产线上,需要将采用EtherNet/IP协议的电池检测设备与采用ProfiNet协议的生产线控制系统进行集成,以实现对电池生产过程的全面监控和数据采集。 二、…...
伪装目标检测(Camouflaged Object Detection, COD)教程
1. 引言 伪装目标检测(Camouflaged Object Detection, COD)是一项计算机视觉任务,旨在识别和分割背景中难以察觉的目标,如动物伪装、隐形物体检测等。由于伪装目标通常与背景高度相似,这项任务比传统的目标检测更具挑…...
烧烤炉出口亚马逊欧盟站CE认证EN1860安全标准
什么是欧盟CE认证: 在欧盟市场“CE”标志属强制性认证标志,不论是欧盟内部企业生产的产品,还是其他国家生产的产品,要想在欧盟市场上自由流通,就必须加贴“CE”标志,以表明产品符合欧盟《技术协调与标准化新…...
动态DNS神器nip.io使用指南:快速实现域名与IP的动态映射--告别配置本地hosts
动态DNS神器nip.io使用指南:快速实现域名与IP的动态映射--告别配置本地hosts 一、项目简介二、快速入门三、进阶配置四、典型应用场景 本文基于开源项目 v1.2.1版本撰写,适用于开发测试、CI/CD等场景 一、项目简介 nip.io 是由Exentrique Solutions开发…...
人工智能 - 机器学习、深度学习、强化学习是人工智能领域的理论基础和方法论
机器学习、深度学习、强化学习是人工智能领域的三大核心方向,各自具有独特的理论基础和方法论。以下是它们的核心理论知识总结: 一、机器学习(Machine Learning, ML) 1. 基础概念 目标:通过数据驱动的方式,让机器从经验中学习规律,完成预测、分类或决策任务。 核心范式…...
数字电路-基础逻辑门实验
基础逻辑门是数字电路设计的核心元件,它们执行的是基本的逻辑运算。通过这些基本运算,可以构建出更为复杂的逻辑功能。常见的基础逻辑门包括与门(AND)、或门(OR)、非门(NOT)、异或门…...
国产编辑器EverEdit - 如虎添翼的功能:快速选择
1 快速选择 1.1 应用场景 快速选择适用于批量选择和修改的场景,比如:变量改名。 1.2 使用方法 1.2.1 逐项快速选择 将光标放置在单词前或单词中,选择主菜单查找 -> 快速选择 -> 快速选择或使用快捷键Ctrl D 注:光标放…...
国内外网络安全政策动态(2025年1月)
▶︎ 1.国家互联网信息办公室发布《个人信息出境个人信息保护认证办法(征求意见稿)》 1月3日,国家互联网信息办公室发布《个人信息出境个人信息保护认证办法(征求意见稿)》。根据《意见稿》,个人信息出境个…...
68页PDF | 数据安全总体解决方案:从数据管理方法论到落地实践的全方位指南(附下载)
一、前言 这份报告旨在应对数字化转型过程中数据安全面临的挑战,并提供全面的管理与技术体系建设框架。报告首先分析了数字化社会的发展背景,强调了数据安全在国家安全层面的重要性,并指出数据安全风险的来源和防护措施。接着,报…...
AI大模型的文本流如何持续吐到前端,实时通信的技术 SSE(Server-Sent Events) 认知
写在前面 没接触过 SSE(Server-Sent Events),AI大模型出来之后,一直以为文本流是用 WebSocket 做的偶然看到返回到报文格式是 text/event-stream,所以简单认知,整理笔记博文内容涉及 SSE 认知,以及对应的 D…...
Electron:使用electron-react-boilerplate创建一个react + electron的项目
使用 electron-react-boilerplate git clone --depth 1 --branch main https://github.com/electron-react-boilerplate/electron-react-boilerplate.git your-project-name cd your-project-name npm install npm start 安装不成功 在根目录加上 .npmrc文件 内容为 electron_…...
Spring Boot三:Springboot自动装配原理
精心整理了最新的面试资料,有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 原理初探 pom.xml 核心依赖在父工程中 spring-boot-dependencies所有的jar包都在这里管理 我们在写或者引入一些依赖的时候,不需要指定版本 启动器 <…...
【ISO 14229-1:2023 UDS诊断全量测试用例清单系列:第十八节】
ISO 14229-1:2023 UDS诊断服务测试用例全解析(ResponseOnEvent_0x86服务) 作者:车端域控测试工程师 更新日期:2025年02月14日 关键词:UDS协议、0x86服务、事件响应、ISO 14229-1:2023、ECU测试 一、服务功能概述 0x86…...
Qt 中使用 SQLite 数据库的完整指南
SQLite 是一款轻量级、嵌入式的关系型数据库,无需独立的服务器进程,数据以文件形式存储,非常适合桌面和移动端应用的本地数据管理。Qt 通过 Qt SQL 模块提供了对 SQLite 的原生支持,开发者可以轻松实现数据库的增删改查、事务处理…...
2024 年 CSDN 博客之星年度评选:技术创作与影响力的碰撞(统计时间2025-02-17 11:06:06)
摘要:在技术的海洋里,每一位博主都像是一座独特的灯塔,用自己创作的光芒照亮他人前行的道路。2024 年 CSDN 博客之星年度评选活动,正是对这些灯塔的一次盛大检阅,让我们看到了众多优秀博主在技术创作领域的卓越表现以及…...
Java零基础入门笔记:(3)程序控制
前言 本笔记是学习狂神的java教程,建议配合视频,学习体验更佳。 【狂神说Java】Java零基础学习视频通俗易懂_哔哩哔哩_bilibili Scanner对象 之前我们学的基本语法中我们并没有实现程序和人的交互,但是Java给我们提供了这样一个工具类&…...
后端生成二维码,前端请求接口生成二维码并展示,且多个参数后边的参数没有正常传输问题处理
一、后端代码 1、controller GetMapping("/generateQRCode/{url}")ApiOperation(value "生成url链接二维码",notes "生成url链接二维码")public JsonResult<NewsQRCodeVo> generateQRCode(PathVariable String url,HttpServletRespons…...
(8/100)每日小游戏平台系列
项目地址位于:小游戏导航 新增一个打地鼠游戏! 打地鼠(Whack-a-Mole)是一款经典的休闲游戏,玩家需要点击随机出现的地鼠,以获取分数。游戏时间有限,玩家需要在规定时间内尽可能多地击中地鼠&am…...
【jar包启动命令简单分享】
最近在做springcloud项目,整理了下启停脚本 批量启动脚本 #!/bin/bashAPP_HOME/data/java/ APP_NAMES("ruoyi-auth.jar""ruoyi-gateway.jar""ruoyi-modules-file.jar""ruoyi-modules-gen.jar""ruoyi-modules-job.jar…...
[Python人工智能] 五十.PyTorch入门 (5)快速搭建神经网络及模型保存
从本专栏开始,作者正式研究Python深度学习、神经网络及人工智能相关知识。前文讲解PyTorch构建分类神经网络。这篇文章将介绍如何利用PyTorch快速构建神经网络,之前的代码比较复杂,通过自定义Net类实现,本文通过Torch函数定义神经网络。前面我们的Python人工智能主要以Tens…...
SpringBoot+Vue+数据可视化的动漫妆造服务平台(程序+论文+讲解+安装+调试+售后等)
感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,我会一一回复,希望帮助更多的人。 系统介绍 在当今数字化高速发展的时代,动漫产业迎来了前所未有的繁荣,动漫…...
Go入门之语言变量 常量介绍
func main(){var a int8 10var b int 5var c int 6fmt.Println("a", a, "b", b, "c", c)d : 10fmt.Printf("a%v leixing%T\n", d, d) } main函数是入口函数,fmt包有三个打印的函数Println,Print,Printf。第…...
基于web的留守儿童网站的设计与实现
开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…...
鸡兔同笼问题
鸡兔同笼问题是这样一个问题: 现有鸡、兔合装在一个笼子里。数头一共100个头,数脚一共300只脚。问有多少只鸡多少只兔? 在这里讨论这个问题的解法当然太小儿科了。但是y_tab这个C语言解释器只提供了1维数组。如果需要用到2维数组时ÿ…...
使用 Spring Boot 和 Canal 实现 MySQL 数据库同步
文章目录 前言一、背景二、Canal 简介三、主库数据库配置1.主库配置2.创建 Canal 用户并授予权限 四.配置 Canal Server1.Canal Server 配置文件2.启动 Canal Server 五.开发 Spring Boot 客户端1. 引入依赖2. 配置 Canal 客户端3. 实现数据同步逻辑 六.启动并测试七.注意事项八…...
中上211硕对嵌入式AI感兴趣,如何有效规划学习路径?
今天给大家分享的是一位粉丝的提问,中上211硕对嵌入式AI感兴趣,如何有效规划学习路径? 接下来把粉丝的具体提问和我的回复分享给大家,希望也能给一些类似情况的小伙伴一些启发和帮助。 同学提问: 中上211,…...
OpenCV中的边缘检测
边缘检测是图像处理和计算机视觉中的关键技术之一,旨在识别图像中像素强度发生显著变化的区域,这些区域通常对应于物体的边界或轮廓。边缘检测在机器视觉中具有重要的需求背景,主要体现在以下几个方面: 图像分割:边缘…...
Python爬虫-猫眼电影的影院数据
前言 本文是该专栏的第46篇,后面会持续分享python爬虫干货知识,记得关注。 本文笔者以猫眼电影为例子,获取猫眼的影院相关数据。 废话不多说,具体实现思路和详细逻辑,笔者将在正文结合完整代码进行详细介绍。接下来,跟着笔者直接往下看正文详细内容。(附带完整代码) …...
家里WiFi信号穿墙后信号太差怎么处理?
一、首先在调制解调器(俗称:猫)测试网速,网速达不到联系运营商; 二、网线影响不大,5类网线跑500M完全没问题; 三、可以在卧室增加辅助路由器(例如小米AX系列)90~200元区…...
