【小梦C嘎嘎——启航篇】内存管理小知识~

news2025/1/12 20:40:14

【小梦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"就会结束打印。

解决方案:将其强转为其他类型即可解决。

错误代码:

在这里插入图片描述

程序运行结果:

在这里插入图片描述

修改后的代码:

在这里插入图片描述

运行结果:

在这里插入图片描述

总结撒花💞

   希望大家通过阅读此文有所收获
   😘如果我写的有什么不好之处,请在文章下方给出你宝贵的意见😊。如果觉得我写的好的话请点个赞赞和关注哦~😘😘😘

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/870179.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mybatis 小结

一、Mybatis 基本构成 MyBatis的整体分为基础支持层、核心处理层、接口。 1.1、基础支持层 1.1.1、数据源模块 MyBatis自身提供了相应的数据源实现&#xff0c;也提供了与第三方接口数据源集成的接口&#xff0c;这些功能都位于数据源模块之中。 1.1.2、事务管理模块 …

FPGA应用学习笔记----定点除法的gold算法流水线设计

猜一个Y0 a和b上下都Y0 分母越接近一&#xff0c;分子就越接近答案 误差&#xff1a; 下一步迭代为 Y的迭代值&#xff1a; 误差值&#xff1a; 代码的实现如上所示

GrapeCity Documents for Imaging Crack

GrapeCity Documents for Imaging Crack 增加了对双面打印的支持。 GcExcel.NET支持PrintOutOptions类中的Duplex枚举&#xff0c;以启用/禁用页面上的双面打印。 枚举中有四个选项&#xff0c;用户可以相应地使用它们来打印工作簿&#xff1a; 双面打印。Default表示打印机的默…

Codeforces Round 892 (Div. 2) C. Another Permutation Problem 纯数学方法 思维题

Codeforces Round 892 (Div. 2) C. Another Permutation Problem 源码&#xff1a; #include <iostream> #include <algorithm> #include <set> #include <map> #include <queue> #include <vector> #include <stack> #include &l…

【数据结构•并查集】矩形

题目描述 在一个平面上有n个矩形。每个矩形的边都平行于坐标轴并且都具有值为整数的顶点。我们用如下的方式来定义块。 每一个矩形都是一个块。 如果两个不同的矩形有公共线段&#xff0c;那么它们就组成了一个新的块来覆盖它们原来的两个块。 例子&#xff1a; 在图1中的矩形…

软考高级架构师——5、系统规划分析与设计方法

系统计划主要用于描述从项目提出、选择到确立的过程&#xff0c;包括系统项目的提出与可行性 分析&#xff0c;系统方案的制订、评价和改进&#xff0c;新旧系统的分析和比较&#xff0c;以及现有软件、硬件和数据 资源的有效利用等问题。 1、项目的提出与选择 项目的立项目标…

Maven从入门到好难

参考文献 永远最好的官网 超赞maven系列文章 1. 为啥要有maven 想当初&#xff0c;刚毕业刚工作&#xff0c;之前学的C&#xff0c;java不懂&#xff0c;部门用的Spring&#xff0c;于是开始学习SSM&#xff0c;妈的&#xff0c;jar包好难整&#xff0c;还要一个个下载好放到…

单片机直驱两相四线步进电机研究

【本文发布于https://blog.csdn.net/Stack_/article/details/132236329&#xff0c;未经允许不得转载&#xff0c;转载须注明出处】 双极性步进电机&#xff08;两相四线步进电机&#xff09;&#xff0c;原理的东西就先不讲太多了&#xff0c;还没搞清楚&#xff0c;边查资料边…

ARTS 挑战打卡的第一周,我学到了这些~

目录 前言 一、学习的内容 二、超时怎么办那就换种思路看题解 三、学习打卡成果展示 3.1 Github的小技巧 3.2 英文文章阅读 3.3 一篇很不错的Java面试题博客 四、学习技巧的总结 前言 关于 ARTS 的释义 ● Algorithm: 每周至少做一个 LeetCode 的算法题 ● Review: 阅读…

Javascript异步编程的4种方法

你可能知道&#xff0c;Javascript语言的执行环境是"单线程"&#xff08;single thread&#xff09;。 所谓"单线程"&#xff0c;就是指一次只能完成一件任务。如果有多个任务&#xff0c;就必须排队&#xff0c;前面一个任务完成&#xff0c;再执行后面一…

使用selenium如何实现自动登录

回顾使用requests如何实现自动登录一文中&#xff0c;提到好多网站在我们登录过后&#xff0c;在之后的某段时间内访问该网页时&#xff0c;不会给出请登录的提示&#xff0c;时间到期后就会提示请登录&#xff01;这样在使用爬虫访问网页时还要登录&#xff0c;打乱我们的节奏…

【Linux】以太网协议——数据链路层

链路层解决的问题 IP拥有将数据跨网络从一台主机送到另一台主机的能力&#xff0c;但IP并不能保证每次都能够将数据可靠的送到对端主机&#xff0c;因此IP需要上层TCP为其提供可靠性保证&#xff0c;比如数据丢包后TCP可以让IP重新发送数据&#xff0c;最终在TCP提供的可靠性机…

数据通信——网络层(ACL)

引言 在网络中会区分三个区域&#xff1a;&#xff08;Trust&#xff09;内网&#xff0c;&#xff08;UnTrust&#xff09;外网&#xff0c;&#xff08;DM2&#xff09;非军事化区域 防火墙在网络中可以阻止DM2对Trust的访问。同理&#xff0c;从Trust到UnTrust或者UnTrust到…

STM32 CubeMX (uart_IAP串口)简单示例

STM32 CubeMX [TOC]( STM32 CubeMX (uart_IAP串口)简单示例) 前言 单片机flash有两部分1.IAP程序和2.APP程序&#xff1b;IAP是烧录工具烧录的&#xff0c;App是串口烧录的 #1.IAP程序设置,程序地址 #2.APP程序设置&#xff0c;程序地址 生成bin文件 fromelf.exe --bin -o …

2023高教社杯数学建模A题 B题C题 D题 E题思路代码分析

文章目录 0 赛题思路1 竞赛信息2 竞赛时间3 建模常见问题类型3.1 分类问题3.2 优化问题3.3 预测问题3.4 评价问题 4 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 竞赛信息 全国大学生数学建模…

指针的进阶--从入门到入土

指针--变态加强版 前言面试题字符指针指针数组数组指针函数指针函数指针数组指向函数指针数组的指针面试题解析结语 前言 掌握指针这块知识的重要性不言而喻&#xff0c;当你觉得自己已经差不多掌握指针的时候&#xff0c;不妨看看下面8道面试题&#xff08;题目从简单到困难&…

三级城市展示省市区树

展示效果 数据库展示 业务代码 /*** 省市区树*/VLicenseApiOperation("查询经纬度")ApiImplicitParam(name "FnCity", value "省市区树", dataType "FnCity")GetMapping("/districtlist")public AjaxResult districtlist…

STM32F429IGT6使用CubeMX配置IIC通信(AT2402芯片)

1、硬件电路 写地址&#xff1a;0xA0 读地址&#xff1a;0xA1 存储容量&#xff1a;256Byte 2、设置RCC&#xff0c;选择高速外部时钟HSE,时钟设置为180MHz 3、配置IIC 4、生成工程配置 5、部分代码 #define IIC_WRITE_ADDR 0xA0 // IIC写地址 #define IIC_READ_ADDR 0xA1 …

数据结构----哈夫曼树

这里写目录标题 基本概念引子基本概念各种路径长度各种带权路径长度结点的带权路径长度树的带权路径长度哈夫曼树 哈夫曼树的构造理论基础构造思想总结 一级目录二级目录二级目录二级目录 一级目录二级目录二级目录二级目录 一级目录二级目录二级目录二级目录 一级目录二级目录…

exec族函数

本节学习exec族函数&#xff0c;并大量参考了以下链接&#xff1a; linux进程---exec族函数(execl, execlp, execle, execv, execvp, execvpe)_云英的博客-CSDN博客 exec族函数函数的作用 我们用fork函数创建新进程后&#xff0c;经常会在新进程中调用exec函数去执行另外一个程…