【小梦C嘎嘎——启航篇】内存管理小知识~
【小梦C嘎嘎——启航篇】内存管理小知识~😎
- 前言🙌
- malloc/calloc/realloc的区别?
- new 与 delete
- new与delete要找好搭档才能保证万无一失
- new 与 delete的内部实现细节是怎么样的呢???
- new 的内部实现细节
- delete的内部实现细节
- 经典问题:malloc/free 与new/delete 的区别是什么???
- 抛异常的基本使用
- 小知识点:cout 流插入 不能打印出char*指针的地址
- 总结撒花💞
😎博客昵称:博客小梦
😊最喜欢的座右铭:全神贯注的上吧!!!
😊作者简介:一名热爱C/C++,算法等技术、喜爱运动、热爱K歌、敢于追梦的小博主!
😘博主小留言:哈喽!😄各位CSDN的uu们,我是你的博客好友小梦,希望我的文章可以给您带来一定的帮助,话不多说,文章推上!欢迎大家在评论区唠嗑指正,觉得好的话别忘了一键三连哦!😘
前言🙌
哈喽各位友友们😊,我今天又学到了很多有趣的知识,现在迫不及待的想和大家分享一下! 都是精华内容,可不要错过哟!!!😍😍😍
malloc/calloc/realloc的区别?
这是一个经典的问题,有时面试也会这么问你。我的理解是:malloc可以向堆区动态申请一段连续的空间,realloc 的话主要是完成扩容操作,其扩容又可以分为两种方式:1.原地扩容 ;2.异地扩容。异地扩容的代价比较高,因为它要在堆区去找一块能够满足需求的空间,然后将原来的数据内容拷贝到新申请的空间里面,然后再把原来申请的空间释放掉。而calloc的话就是在malloc的基础上,能够将自己申请的空间进行初始化操作。以上就是他们三者的区别与联系啦~
new 与 delete
在C语言中我们知道有malloc ,realloc,calloc 这些可以在堆区中申请资源,可以用free释放掉堆上开辟的空间。那为什么C++还自己搞一套呢???不要问,C嘎嘎祖师爷那么设计一定有他的道理!!!接下来,我就来分析一下为什么。
new与delete要找好搭档才能保证万无一失
由于我们场景需求的多样,因此new与delete产生了不同的搭档方式以满足我们的需求。简单概括为:
- 一个变量空间的申请与释放:new 变量类型(val) <-----> delete 变量名
- 一个变量空间的申请与释放:new 变量类型【变量个数】(val) <-----> delete【】 变量名
#include<iostream>
using namespace std;class A
{
public:A(int a = 0):_a(a){cout << "A(int a = 0)" << endl;}~A(){cout << "~A()" << endl;}
private:int _a;
};int main()
{int* a = new int(10);cout << *a << endl;delete a;A* ptr1 = new A[10];delete[] ptr1;return 0;
}

new与delete要找好搭档才能保证万无一失,如果随意搭档可能会出错的。例如下面这个场景就会导致运行错误。
class A
{
public:A(int a = 0):_a(a){cout << "A(int a = 0)" << endl;}~A(){cout << "~A()" << endl;}
private:int _a;
};int main()
{int* a = new int(10);cout << *a << endl;A* ptr1 = new A[10];delete ptr1;//delete[] ptr1;return 0;
}

因此,我们在使用的时候,一定要根据场景的需求去选择new 与 delete 的 匹配搭档。
new 与 delete的内部实现细节是怎么样的呢???
new 的内部实现细节
其实new 之所以可以申请空间并且完成初始化操作,其实其内部是调用了 malloc 和 构造函数来实现的。那它们又是怎么调用malloc和构造的呢?内部实现的细节是怎么样的? 其实这里使用了封装的方法,其内部实现是写了一个operator new函数,这个函数里面封装了malloc函数的调用以及抛异常的实现。因此,operator new函数就完成了new的开空间和如果new失败了会抛异常的功能。然后调用new,编译器会自动调用构造函数进行对象的初始化操作。
delete的内部实现细节
其实delete之所以可以释放空间并且完成对象资源清理的工作,其实其内部是调用了free函数 和 析构函数来实现的。那它们又是怎么调用free函数 和 析构函数的呢?内部实现的细节是怎么样的? 其实这里也使用了封装的方法,其内部实现是写了一个operator delete函数,这个函数里面封装了free函数的调用。因此,operator delete函数就完成了对象资源的释放。然后调用delete,编译器会自动调用析构函数进行对象空间的释放。
从他们内部实现的细节可以看出,如果只是对内置类型变量,那么使用malloc + free 与使用 new + delete 都可以完成空间的开辟和释放。但是,对于自定义类型就只能用new+delete。最主要的原因就是:new和delete会自动调用构造函数和析构函数,而malloc和free不能。
经典问题:malloc/free 与new/delete 的区别是什么???
我的理解是:
-
从语法角度上看:
malloc ,free是函数,而new与delete是操作符。malloc需要自己手动计算所要申请空间的大小而new直接加类型然后在后面【】里面写上对象个数即可。malloc 返回的是vold*指针需要强转,而new不用,返回的就是该对象类型的指针。malloc开辟失败是会返回NULL,我们需要自己写一个检查代码来判断是否开辟失败,而new开辟失败会抛出异常,无需我们写检查代码。malloc只能完成申请空间的功能,而new既可以申请空间又可以进行初始化。
-
从底层原理实现的角度上看:
申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new
在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成
空间中资源的清理
抛异常的基本使用
C++中的new有抛异常的功能。而try()catch()则可以去捕获new抛出的异常。
首先需要将要检查的代码放在try()里面,或者在这里面进行调用,才能够对该代码段进行异常的检查和捕获。一旦捕获到异常,就会自动跳转到catch()里面,然后进行异常的处理。下面是一个在32位平台上的应用举例:
void func()
{char* p1 = new char[0x7fffffff];cout << (void*)p1 << endl;cout << "hello world" << endl;
}int main()
{try{func();}catch (const exception& e){cout << e.what() << endl;}return 0;
}
运行结果截图:

小知识点:cout 流插入 不能打印出char*指针的地址
原因:cout 会自动识别其为字符串,并按照字符串的格式进行打印,遇到"/0"就会结束打印。
解决方案:将其强转为其他类型即可解决。
错误代码:

程序运行结果:

修改后的代码:

运行结果:

总结撒花💞
希望大家通过阅读此文有所收获!
😘如果我写的有什么不好之处,请在文章下方给出你宝贵的意见😊。如果觉得我写的好的话请点个赞赞和关注哦~😘😘😘
相关文章:
【小梦C嘎嘎——启航篇】内存管理小知识~
【小梦C嘎嘎——启航篇】内存管理小知识~😎 前言🙌malloc/calloc/realloc的区别?new 与 deletenew与delete要找好搭档才能保证万无一失 new 与 delete的内部实现细节是怎么样的呢???new 的内部实现细节dele…...
ClickHouse查看执行计划(EXPLAIN语法)
1.EXPLAIN 语法示例 EXPLAIN [AST | SYNTAX | QUERY TREE | PLAN | PIPELINE | ESTIMATE | TABLE OVERRIDE] [setting value, ...] [ SELECT ... | tableFunction(...) [COLUMNS (...)] [ORDER BY ...] [PARTITION BY ...] [PRIMARY KEY] [SAMPLE BY ...] [T…...
线程池
线程池 什么是线程池? 想象一下 假设我是个漂亮妹子,这时候接受了舔狗A的表白,随着时间的推移,逐渐不喜欢A这小子了,于是我就想换个男朋友,可是 1.处理分手,需要消耗一定成本 2.再找一个新对象…...
配置:Terminal和oh-my-posh
目录 命令行安装oh-my-posh查看安装情况配置PowerShell启用oh-my-posh、设置主题配色安装字体Terminal中的配置 命令行安装oh-my-posh Set-ExecutionPolicy Bypass -Scope Process -Force; Invoke-Expression ((New-Object System.Net.WebClient).DownloadString(https://ohmy…...
数据结构--BFS求最短路
数据结构–BFS求最短路 BFS求⽆权图的单源最短路径 注:⽆权图可以视为⼀种特殊的带权图,只是每条边的权值都为1 以 2 为 b e g i n 位置 以2为begin位置 以2为begin位置 代码实现 //求顶点u到其他顶点的最短路径 void BFS_MIN_Distance(Graph G, int u…...
FPGA应用学习笔记----定点除法的gold算法流水线设计
猜一个Y0 a和b上下都Y0 分母越接近一,分子就越接近答案 误差: 下一步迭代为 Y的迭代值: 误差值: 代码的实现如上所示...
Nginx转发的原理和负载均衡
一、Nginx转发的原理 Nginx是一个高性能的反向代理服务器,它可以用于实现请求的转发和负载均衡。以下是Nginx转发的基本原理: 客户端发送请求:客户端向Nginx服务器发送HTTP请求。 Nginx接收请求:Nginx服务器接收到客户端的请求。…...
怎么换ip地址 电脑切换ip地址方法
互联网时代,IP地址是我们在网络上进行通信和访问的身份标识。有时候,我们可能需要更改IP地址,以便获得更好的网络体验或绕过某些限制。本文将介绍如何使用深度IP转换器来更改IP地址。 1:了解IP地址 IP地址是一个由数字和点组成的标…...
软件设计基础
巩固基础,砥砺前行 。 只有不断重复,才能做到超越自己。 能坚持把简单的事情做到极致,也是不容易的。 软件项目管理。 在经历了软件危机和大连的软件项目失败以后,人们对软件工程专业的现状进行了多次分析。得出了普遍性的结论&…...
OptaPlanner笔记5
2.4 与spring boot集成 2.4.4 添加依赖 <dependency><groupId>org.optaplanner</groupId><artifactId>optaplanner-spring-boot-starter</artifactId> </dependency>2.4.8 创建求解器服务 import org.optaplanner.core.api.solver.Solv…...
PS注意事项优漫动游
PS入门注意事项AdobePhotoshop是目前最流行的平面设计软件之一。可以说,只要你接触平面设计,那么无论早晚,你都要和它打交道。关于Photoshop,要说的实在太多太多,但不论你想让它成为你的左膀右臂,或者仅仅是…...
matplotlib 判断鼠标是否点击在当前线上
在开发中有一个需求:对生成的一条线进行拖拽。 我将这个方法实现在线所在的类里,这个过程中需要判断鼠标是否点击在当前线上,从而实现拖拽。 实现代码如下: # 点击事件 def on_press(self,event):if event.inaxes ! self.ax:retur…...
bash中(冒号破折号)的用法 —— 筑梦之路
${PUBLIC_INTERFACE:-eth0} :- 的用途是什么? 含义:如果 $PUBLIC_INTERFACE 存在且不是 null,则返回其值,否则返回 "eth0"。 ${parameter:-word} 使用默认值。如果 parameter 未设置或为 null,则 word 的扩…...
LeetCode150道面试经典题--同构字符串(简单)
1.题目 给定两个字符串 s 和 t ,判断它们是否是同构的。如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的。每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,…...
Redis - 数据类型映射底层结构
简介 从数据类型上体现就是,同一个数据类型,在不同的情况下会使用不同的编码类型,底层所使用的的数据结构也不相同。 字符串对象 字符串对象的编码可以是 int、raw 和 embstr 三者之一。 embstr 编码是专门用于保存简短字符串的一种优化编…...
MySQL数据库表的增删查改 - 进阶
一,数据库约束 1.1 约束对象 not null - 该列不能为空unique - 保证该列的每一行都不一样default - 规定没有给列赋值时的默认值(自定义)primary key - not null 和 unique 的结合,会给该列添加一个索引࿰…...
8086汇编语言工作环境 百度网盘下载
链接:https://pan.baidu.com/s/1-1K7gX859xejaUK70OTgtw?pwdbfa5 提取码:bfa5 为了方便下载,找了很多资料,也是从其他人那边分享过来的,也方便其他人 文件内容:...
ES6 解构
解构的语法 … {} 解构的语法中,...(展开运算符)和 {}(对象字面量)扮演着不同的角色。 ...(展开运算符): 在解构中,... 被用作展开运算符,用于将数组或对象中…...
React三个状态时触发的相应钩子
01.初始化状态。 这个阶段由render()函数触发; 1.constructor(); 2.componentWillMount(); 在17版本以后改为UNSAFE_componentWillMount() reason:react为组件异步渲染做准备; 3.render(); 4.componentDidMount(); 这…...
阿里云服务器部署Drupal网站教程基于CentOS系统
阿里云百科分享如何在CentOS 7操作系统的ECS实例上搭建Drupal电子商务网站。Drupal是使用PHP语言编写的开源内容管理框架(CMF),它由内容管理系统(CMS)和PHP开发框架(Framework)共同构成。它用于…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...
【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...
PostgreSQL——环境搭建
一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在࿰…...

