【C++】C/C++内存管理
文章目录
- 1. C/C++内存分布
- 2. C语言当中的动态内存管理
- 3. C++ 内存管理方式
- 3.1 new/delete操作内置类型
- 3.2 new和delete操作自定义类型
- 4. operator new 和operator delete 函数
- 5. new和delete的实现原理
- 5.1 内置类型
- 5.2 自定义类型
- 6. 定位new表达式(placement-new)
- 7. 常见面试题
- 7.1 malloc/free 和 new/delete区别
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在哪里:栈
pChar3在哪里: 栈 *pChar3在哪里:代码段(常量区)
ptr1在哪里:栈 *ptr1在哪里:堆
sizeof(num1) = 40
sizeof(char2) = 5 strlen(char2)= 4
sizeof(pChar3) = 4/8 strlen(pChar3)= 4
sizeof(ptr1) = 4
sizeof 和strlen的区别:

说明:
- 栈又叫堆栈–非静态局部变量/函数参数/返回值等等,栈是向下增长的
- 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享内存,做进程间通信
- 堆用于程序运行时动态内存分配,堆是向上增长的
- 数据段存储全局数据和静态数据
- 代码段–可执行的代码只读常量
2. C语言当中的动态内存管理
文章
3. C++ 内存管理方式
C语言的内存管理方式在C++当中可以继续使用,但是有些地方用起来比较麻烦,因此C++提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理
3.1 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[]匹配起来使用
3.2 new和delete操作自定义类型
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 全局函数来释放空间
/*
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 实际也是通过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 函数申请空间
- 在申请的空间上执行构造函数,完成对象的构造
- delete的原理
- 在空间上执行析构函数,完成对象中资源的清理工作
- 调用operator delete函数释放对象的空间
- new T[N]的原理
- 调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对象空间的申请
- 在申请的空间上执行N次构造函数
- delete T[N]
- 在释放的对象上执行N次析构函数,完成N个对象当中资源的清理
- 调用operator delete[]释放空间,实际在调用operator delete[]中调用operator delete来释放资源
6. 定位new表达式(placement-new)
定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象
使用格式:
new(place_address)type或者new (place_address)type (initializer-list)
place_address必须是一个指针,initializer-list是类型的初始化列表
使用场景:
定位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;
}
7. 常见面试题
7.1 malloc/free 和 new/delete区别
它们的共同点:都是从堆上申请空间,并且需要手动释放。不同的地方:
- malloc/free是函数,而new/delete是操作符
- malloc申请的空间不会初始化,new可以初始化
- malloc申请空间的时候需要手动计算空间大小并传递,new只需要在后面加上空间的类型就可以了,如果是多个对象只需要[]当中指定个数就可以了
- malloc返回值为void*必须强转,new不需要,因为后面跟的就是空间的类型
- malloc申请空间失败的时候返回NULL,,因此必须判空,new不需要,new需要捕获异常
- 申请自定义类型的对象的时候,malloc只会开辟空间,不会调用构造函数,而new在申请空间后会调用构造函数完成对对象的初始化,delete在释放空间之前会调用析构函数完成空间当中资源的清理
相关文章:
【C++】C/C++内存管理
文章目录1. C/C内存分布2. C语言当中的动态内存管理3. C 内存管理方式3.1 new/delete操作内置类型3.2 new和delete操作自定义类型4. operator new 和operator delete 函数5. new和delete的实现原理5.1 内置类型5.2 自定义类型6. 定位new表达式(placement-new)7. 常见面试题7.1 …...
【测试】自动化测试02
努力经营当下,直至未来明朗! 文章目录前言 回顾 预告一、常见的元素操作1. 输入文本sendKeys()2. 点击click3. 提交submit(通过回车键提交)4. 清除clear5. 获取文本getText()6. 获取属性对应的值getAttribute()7. 查看title和ur…...
Python空间分析| 02 利用Python计算空间局部自相关(LISA)
局部空间自相关 import esda import numpy as np import pandas as pd import libpysal as lps import geopandas as gpd import contextily as ctx import matplotlib.pyplot as plt from geopandas import GeoDataFrame from shapely.geometry import Point from pylab im…...
idea快捷编码:生成for循环、主函数、判空非空、生成单例方法、输出;自定义快捷表达式
前言 idea可根据输入的简单表达式进行识别,快速生成语句 常用的快捷编码:生成for循环、主函数、判空非空、生成单例方法、输出 自定义快捷表达式 博客地址:芒果橙的个人博客 【http://mangocheng.com】 一、idea默认的快捷表达式查看 Editor…...
【Spring】@Value注入配置文件 application.yml 中的值失败怎么办
本期目录一、 问题背景二、 问题原因三、 解决方法一、 问题背景 今天碰到的问题是用 Value 注解无法注入配置文件 application.yml 中的配置值。 检查过该类已经交给 Spring 容器管理了,即已经在类上加了 Configuration 和 ConfigurationProperties(prefix &quo…...
CleanMyMac清理工具软件功能优势介绍
CleanMyMac更新最新版本x4.12,完美适配新版系统macOS10.14,拥有全新的界面。CleanMyMac可以让您安全、智能地扫描和清理整个系统,删除大型未使用的文件,减少iPod库的大小,最精确的应用程序卸载,卸载不必要的…...
【面试题】对JS中的事件冒泡、事件捕获、事件委托的理解
大厂面试题分享 面试题库后端面试题库 (面试必备) 推荐:★★★★★地址:前端面试题库DOM事件流(event flow )存在三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段。Dom标准事件流的触发的先…...
SAP 理解合并会计报表
随着企业集团的发展,集团内部会出现越来越多的公司;复杂的公司结构和复杂的集团内业务,使得集团内部管理困难重重,信息渠道严重失灵。除了内部管理的需要,企业还有义务向相关方提供详细的和及时的信息。ERP中的合并会计…...
Ubuntu 命令常用命令——定时启动程序
crontab -e 语法 crontab[ -u user ] file或 crontab[ -u user ] { -l | -r | -e }说明: crontab是用来让使用者在固定时间或固定间隔执行程序之用,换句话说,也就是类似使用者的时程表。 -U Lser 是指设定指定user的时程表,这个前提是你必…...
笔试题(十三):走迷宫
# 描述 # 定义一个二维数组 N*M ,如 5 5 数组下所示: # int maze[5][5] { # 0, 1, 0, 0, 0, # 0, 1, 1, 1, 0, # 0, 0, 0, 0, 0, # 0, 1, 1, 1, 0, # 0, 0, 0, 1, 0,}; # 它表示一个迷宫,其中的1表示墙壁,0表示可以走的路&#…...
Gradle相关的知识学习
这里有一套博客文章写的比较通俗易懂:https://www.jianshu.com/p/8e1ddd19083a...
SpringMVC的工作原理
SpringMVC的工作原理流程图 SpringMVC流程 1、 用户发送请求至前端控制器DispatcherServlet。 2、 DispatcherServlet收到请求调用HandlerMapping处理器映射器。 3、 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截…...
问卷数据分析流程
文章目录一、数据合并1. 读取数据2. 数据预览二、数据清洗1. 检验ID是否重复,剔除ID重复项2. 剔除填写时间小于xx分钟的值3.处理 量表题 一直选一个选项的问题三、数据清洗1.1 将问卷单选题的选项code解码,还原成原来的选项1.2 自动获取单选题旧的选项列…...
【观察】Solidigm P44 Pro SSD评测:原厂品质+软硬兼施=性能怪兽
众所周知,目前SSD(固态硬盘)已取代HDD(机械硬盘)成为电脑中常见的存储设备,特别是在技术创新的持续推动下,如今SSD的速度和效率都在不断地提高,从SATA2 3GB发展到SATA3 6GBÿ…...
String对象的创建和比较
String类的概述 String类:代表字符串。 Java 程序中的所有字符串字面值(如 “abc” )都作 为此类的实例实现。 String是JDK中内置的一个类:java.lang.string 。 String表示字符串类型,属于引用数据类型,不…...
09 OpenCV图形检测
1 轮廓描边 cv2.findContours() 函数是OpenCV中用于寻找轮廓的函数之一。它可以用于在二值图像中查找并检测出所有的物体轮廓,以及计算出这些轮廓的各种属性,例如面积、周长、质心等。 cv2.findContours() 函数的语法如下: contours, hiera…...
解密Teradata与中国市场“分手”背后的原因!国产数据库能填补空白吗?
2月15日,西方的情人节刚刚过去一天,国内IT行业就爆出一个大瓜。 继Adobe、甲骨文、Tableau、Salesforce之后,又一个IT巨头要撤离中国市场。 Teradata天睿公司官宣与中国市场“分手”,结束在中国的直接运营。目前,多家…...
Bernstein-Vazirani算法
B-V算法 (1) 问题描述 给定布尔函数f:{0,1}n→0,1f:{\left\{ {0,1} \right\}^n} \to{0,1}f:{0,1}n→0,1, 函数fff的值是由输入比特串xxx和确定的比特串sss做模2意义下的内积:f(x)x⋅s(mod2),f\left( x \right) x \cdot s\left( {\bmod 2} \right),f(x)x⋅s(mod2),…...
华为OD机试 - 相对开音节 | 备考思路,刷题要点,答疑 【新解法】
最近更新的博客 【新解法】华为OD机试 - 关联子串 | 备考思路,刷题要点,答疑,od Base 提供【新解法】华为OD机试 - 停车场最大距离 | 备考思路,刷题要点,答疑,od Base 提供【新解法】华为OD机试 - 任务调度 | 备考思路,刷题要点,答疑,od Base 提供【新解法】华为OD机试…...
MyBatis
一、MyBatis环境搭建创建工程启动idea开发工具,选择工具栏中的“file”--“new”--“project”选项弹出“new project”对话框,编辑项目名称 选择maven项目,项目路径 单击 create 创建即可。引入相关依赖<dependencies><dependency&…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...
