【C++入门】new和delete(C/C++内存管理)
目录
- 1.C/C++内存分布
- 2.C语言中动态内存管理方式
- 3.C++内存管理方式
- 3.1new/delete操作内置类型
- 3.2new和delete操作自定义类型
- 4.operator new与operator delete函数
- 5.new和delete的实现原理
- 5.1内置类型
- 5.2自定义类型
- 6.malloc/free和new/delete的区别
- 7.定位new表达式(了解)
1.C/C++内存分布
我们先来看一个小问题:
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);
}
问题:
下面我们就来简单分析一下:
首先
globalVar是一个全局变量,其次staticGlobalVar是一个静态全局变量,staticVar是静态局部变量,都在静态区(数据段)。最后localVar是个局部变量,num1是个整型数组,那它们是在栈上的。
char2这个字符数组也是在栈上的,只是用代码段(常量区)的常量字符串去初始化它了,然后*char2,char2是数组首元素地址,那*char2就是数组首元素,也是是在栈上。pChar3是一个局部指针变量,在栈上,但是pChar3指向常量区的常量字符串,所以*pChar3是在常量区。ptr1也是局部指针变量,在栈上,ptr1指向的空间是malloc出来的,在堆上。
我们下面再来看几个题:
sizeof(num1),num1是10个元素的整型数组,数组名在sizeof里面代表整个数组,所以答案是40;sizeof(char2), char2里面有5个字符(字符串隐藏结束标志\0),所以答案是5;strlen(char2)求字符串长度,是4 ;sizeof(pChar3),指针变量,大小为4或8字节;strlen(pChar3),同样求长度是4;sizeof(ptr1),指针变量,4或8字节。
我们再来看一下C/C++内存区域划分:
说明:
- 栈又叫堆栈–非静态局部变量/函数参数/返回值等等,栈是向下增长的。
- 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信。
- 堆用于程序运行时动态内存分配,堆是可以上增长的。
- 数据段–存储全局数据和静态数据。
- 代码段–可执行的代码/只读常量。
2.C语言中动态内存管理方式
我们简单看一下C语言中的内存管理方式:
void Test()
{int* p1 = (int*)malloc(sizeof(int));free(p1);// 1.malloc/calloc/realloc的区别是什么?int* p2 = (int*)calloc(4, sizeof(int));int* p3 = (int*)realloc(p2, sizeof(int) * 10);free(p3);
}
malloc和calloc它们都可以在堆上开辟内存空间,除了传参不一样之外,两者的区别在于calloc会把开辟出来的空间全部初始化为0,而malloc不会去初始化。realloc可以扩容(有两种方式一种是原地扩、另一种是异地扩)。
3.C++内存管理方式
C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因 此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。
3.1new/delete操作内置类型
在C语言中:
我们使用
malloc/calloc去申请空间,需要自己计算需要开辟空间的大小,然后传参,返回值呢是void*,还需要我们自己强转。
那么在C++中我们可以这样:
在这里用一个操作符new,我们不需要sizeof计算大小,可以直接给类型,而且也不需要强制类型转换。
同样的动态申请10个整型大小的空间:
C++搞出new和delete更多的是为了自定义类型,那new和delete操作自定义类型我们后面也会专门讲解。此外内置类型new出来的空间是没有被初始化的,但是C++其实有方法去对new出来的空间进行初始化:
上图就是动态申请一个int类型大小空间并初始化为10
对于我们使用new动态开辟的数组,我们可以初始化吗?
也是可以的:
下面我们再来看一个和new操作符“配套”的delete:
在C语言中使用
malloc/calloc在堆上开辟出来的空间需要要使用free释放。
那在C++中我们new出来的空间需要使用一个操作符叫做delete:
同样的使用new动态开辟的数组销毁:
注意delete后面加一个方括号。
注意:匹配起来使用。
申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[]和delete[]
3.2new和delete操作自定义类型
我们上面提到:C++使用
new和delete更多的是为了自定义类型,那接下来我们就来看一下new和delete对于自定义类型有什么特别的地方。
下面我们举个简单的例子:
class A
{
public:A(int a = 0): _a(a){cout << "A():" << this << endl;}~A(){cout << "~A():" << this << endl;}
private:int _a;
};
对于下面这两种写法有什么区别:
用malloc就只是开辟了空间。用new除了开辟空间还自动调用了构造函数进行初始化。free只是释放了空间;delete除了释放指针指向的空间还会调用析构函数对自定义类型进行析构。
总结:
在申请和释放自定义类型的空间时,new会自动调用构造函数,delete会自动调用析构函数,而malloc与free不会。
4.operator new与operator delete函数
虽然这两个函数的函数名是operator 操作符,但是, operator new与operator delete并不是new和delete的重载,operator new与operator delete是库里面的两个全局的函数。
这里 new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间 。
下面我们来看一下它们的底层实现:
operator new实际也是借助malloc来申请空间的,申请成功直接返回,申请失败则抛异常。
operator delete实际也是利用free来释放空间的。
通过上述两个全局函数的实现知道,operator new 实际也是通过malloc来申请空间,如果 malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的。
5.new和delete的实现原理
5.1内置类型
如果申请的是内置类型的空间,new和malloc,delete和free基本类似,不同的地方是: new/delete申请和释放的是单个元素的空间,new[]和delete[]申请的是连续空间,而且new在申请空间失败时会抛异常,malloc会返回NULL。
5.2自定义类型
- new的原理
- 调用operator new函数申请空间,operator new实际又调用malloc
- 在申请的空间上执行构造函数,完成对象的构造
- delete的原理
- 在要释放的对象空间上执行析构函数,完成对象中资源的清理工作
- 调用operator delete函数,operator delete实际调free释放对象的空间
- new T[N]的原理
- 调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对象空间的申请
- 在申请的空间上执行N次构造函数
- delete[]的原理
- 在要释放的对象空间上执行N次析构函数,完成N个对象中资源的清理
- 调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释放空间
6.malloc/free和new/delete的区别
malloc/free和new/delete的共同点是:都是从堆上申请空间,并且需要用户手动释放。
不同的地方是:
- malloc和free是函数,new和delete是操作符
- malloc申请的空间不会初始化,new可以初始化
- malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可,如果是多个对象,[]中指定对象个数即可
- malloc的返回值为void*, 在使用时必须强转,new不需要
- malloc申请空间失败时,返回的是NULL,因此使用时要判空
- 申请自定义类型对象时,malloc/free只会开辟和释放空间,不会调用构造函数与析构函数,而new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理
7.定位new表达式(了解)
定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象。
使用格式:
new (place_address) type或者
new (place_address) type(initializer-list)
place_address必须是一个指针,initializer-list是参数列表
定位new表达式在实际中一般是配合内存池使用。
因为内存池分配出的内存没有初始化,所以如果是自定义类型的对象,需要使用定位new显式调用构造函数进行初始化。
相关文章:
【C++入门】new和delete(C/C++内存管理)
目录 1.C/C内存分布2.C语言中动态内存管理方式3.C内存管理方式3.1new/delete操作内置类型3.2new和delete操作自定义类型 4.operator new与operator delete函数5.new和delete的实现原理5.1内置类型5.2自定义类型 6.malloc/free和new/delete的区别7.定位new表达式(了解…...
C++设计模式之桥接模式
文章目录 一、桥接模式二、std::error_code与设计模式(桥接模式)参考 一、桥接模式 在C中,桥接模式通常涉及以下几个角色: 抽象类接口(Abstraction):定义抽象部分的接口,并维护一个…...
前端速查速记系列----评论列表
小程序评论列表 效果图 wxml代码 <view id"econtent"><block wx:for"{{commentlist}}" wx:for-item"item" wx:for-index"index" wx:key"{{item.id}}"><view class"box1"><view class"…...
hiredis的安装与使用
hiredis的介绍 Hiredis 是一个用于 C 语言的轻量级、高性能的 Redis 客户端库。它提供了一组简单易用的 API,用于与 Redis 数据库进行交互。Hiredis 支持 Redis 的所有主要功能,包括字符串、哈希、列表、集合、有序集合等数据结构的读写操作,…...
【InsCode】InsCode打造的JavaSE与Linux命令互融的伪Linux文件系统小项目
🧑💻作者名称:DaenCode 🎤作者简介:啥技术都喜欢捣鼓捣鼓,喜欢分享技术、经验、生活。 😎人生感悟:尝尽人生百味,方知世间冷暖。 📖所属专栏:Ja…...
“深入解析JVM:探索Java虚拟机的内部机制“
标题:深入解析JVM:探索Java虚拟机的内部机制 摘要:本文将深入探索Java虚拟机(JVM)的内部机制,包括JVM的基本结构、内存管理、垃圾回收机制和即时编译器等。通过对JVM内部机制的详细解析,我们可…...
内网远程控制总结
前言 在内网渗透过程中,会碰到远程控制soft或者其他,这里针对远程控制软件做如下总结。 远程控制软件 向日葵篇 向日葵查看版本 向日葵(可以攻击) 针对向日葵的话其实如果有本地安装的话,是有可能存在漏洞的。这…...
Excel显示此值与此单元格定义的数据验证限制不匹配怎么办?
总结:1、在编辑excel文档的时候,弹出此时预测单元格定义的数据验证,限制不匹配的提示。2、这是我们点击菜单来的数据菜单。3、然后点击数据工具栏的数据验证下拉按钮。4、在弹出的菜单中选择数据验证的菜单项。5、然后在打开的窗口中点击左下…...
mysql(八)事务隔离级别及加锁流程详解
目录 MySQL 锁简介什么是锁锁的作用锁的种类共享排他锁共享锁排它锁 粒度锁全局锁表级锁页级锁行级锁种类 意向锁间隙临键记录锁记录锁间隙锁 加锁的流程锁的内存结构加锁的基本流程根据主键加锁根据二级索引加锁根据非索引字段查询加锁加锁规律 锁信息查看查看锁的sql语句 数据…...
华为云Stack的学习(二)
三、华为云Stack产品组件 FunsionSphere CPS 提供云平台的基础管理和业务资源(包括计算资源和存储资源)。采用物理服务器方式部署在管理节点。可以做集群的配置,扩容和运维管理。 Service OM 提供云服务的运维能力,采用虚拟化方…...
好用的网页制作工具就是这6个,快点来看!
对于网页设计师来说,好用的网页设计工具是非常重要的,今天本文收集了6个好用的网页设计工具供设计师自由挑选使用。在这6个好用的网页设计工具的帮助下,设计师将获得更高的工作效率和更精致的网页设计效果,接下来,就一…...
一文讲通物联网嵌入式
最近有很多同学问我,物联网近几年一直是科技的热点,嵌入式和物联网有什么关系呢?我在这里统一给大家讲解一下。 嵌入式是应用于物联网产品方向的一种嵌入式操作系统。类似于Android系统是谷歌开发的移动操作系统,嵌入式实际上也是…...
Unity3D Pico VR 手势识别 二
Unity3D Pico VR 手势识别_Cool-浩的博客-CSDN博客 此篇主要讲解怎么手势追踪,手势姿态自定义预制识别,不会导入SDK和配置环境的请看上一章节 环境要求 SDK 版本:2.3.0 及以上PICO 设备型号:PICO Neo3 和 PICO 4 系列PICO 设备系…...
ubuntu中使用iptables限制端口
脚本 #!/bin/bash#关闭所有端口 echo "关闭所有入口" iptables -P INPUT DROP iptables -P FORWARD DROP#允许所有已建立的连接和相关连接的回复数据包通过 iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT#允许ping iptables -A INPUT -p…...
Orchestrator介绍二 自身高可用性方案
目录 获得 HA 的方法 一 没有高可用性 (No high availability) 使用场景 架构组成 架构图 二 半高可用性(Semi HA) 三 基于共享数据库后端高可用(HA via shared backend) 四 基于Raft协议高可用 五…...
成集云 | 旺店通多包裹数据同步钉钉 | 解决方案
源系统成集云目标系统 方案介绍 随着品牌电商兴起,线上线下开始逐渐融为一体,成集云以旺店通ERP系统为例,通过成集云-旺店通连接器,将旺店通ERP系统多包裹数据同步至钉钉实现数据互通,帮助企业解决了电商发货存在的错…...
什么是字体图标(Icon Font)?如何在网页中使用字体图标?
聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 字体图标(Icon Font)⭐ 如何在网页中使用字体图标⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&a…...
Blender文件云端GPU渲染
本文介绍如何在 GPU云平台vast.ai 上渲染Blender动画的技术指南,假设你已使用 vast.ai 并知道如何启动实例,这里的重要步骤是为实例选择正确的映像。 推荐:用 NSDT编辑器 快速搭建可编程3D场景 使用 nvidia/cuda:11.4.1-cudnn8-devel-ubuntu2…...
C++——引用
引用的概念 引用不是新定义一个变量,而是给已存在的变量取一个别名,编译器不会因为引用变量而开辟内存空间,它和它引用的变量公用同一块空间。 相当于是给被引用的变量取了一个小名,但是相当于是同一个变量。 类型& 引用变…...
Flask入门一 ——虚拟环境及Flask安装
Flask入门一 ——虚拟环境及Flask安装 在大多数标准中,Flask都算是小型框架,小到可以称为“微框架”,但是并不意味着他比其他框架功能少。Flask自开发伊始就被设计为可扩展的框架。Flask具有一个包含基本服务的强健核心,其他功能…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
















