【C++杂货铺】内管管理


目录

🌈前言🌈

📁 C/C++中内存分布

📁 new 和 delete的使用

📁 new 和 delete的优点

📁 new 和 delete的原理

 📂 operator new 和 operator delete函数

 📂 内置类型

 📂 自定义类型

📁 内存泄漏

📁 总结


🌈前言🌈

        欢迎收看本期【C++杂货铺】,本期内容讲解C++内存管理。包含了C++中内存分布情况,如何进行内存管理,使用new和delete操作符开辟/释放空间等,此外将介绍C++中new 和 delete的优点和原理。

        此外,本期内容可能会涉及到类和对象的部分概念,如果你还不是很了解,可以快速阅览以下文章:

【C++杂货铺】详解类和对象 [上]-CSDN博客

【C++杂货铺】详解类和对象 [中]-CSDN博客

【C++杂货铺】详解类和对象 [下]-CSDN博客

📁 C/C++中内存分布

        程序运行会被加载到内存,程序的代码和数据则会在内存中存储在不同地方,通过内存地址进行访问。

        内存地址是计算机中用来标识存储单元位置的一个唯一的数字。在计算机中,每个存储单元都有一个唯一的地址,通过这些地址可以访问和操作存储器中的数据。内存地址通常用十六进制表示。

        为了方便管理不同的类型的数据,如全局变量和局部变量,就会在内存中划分出不同区域。

当然这只是简单的了解一下内存分布,如果你学过操作系统的内容,你就会知道,C/C++中的内存概念其实都是虚拟内存,不是真实的物理内存。

        上图中,不同书籍可能会有偏差,如果只学过语言,只需要知道有栈,堆,数据段,代码段即可。其中栈存放局部变量,形参等数据,堆则是由程序员自己手动开辟,存放数据。

        所以,堆区则是我们进行内存管理的区域了。

📁 new 和 delete的使用

        学过C语言可能知道,想要在C语言中开辟内存空间需要使用malloc函数,释放资源使用free函数。

        下图是malloc和free函数的使用示例。

开辟1个int类型数据的空间
int* pa = (int*)malloc(sizeof(int));
if(pa == NULL )return 1;free(pa);开辟10个int类型数据的空间
int* parr = (int*)malloc(sizeof(int) * 10 );释放连续地址空间只需要给出首元素地址即可
free(parr);

        我们可以看出使用malloc函数非常的不方便,例如只开辟空间,不能完成初始化;需要手动判断内存是否开辟成功。

        此外,最重要的是,对于自定义类型,是需要构造函数初始化,但是malloc开完空间后,不能调用构造函数。

        所以C++语言就引入了两个操作符new 和 delete。

        下图是new 和 delete操作符的使用示例。

int* pa = new int;
delete pa;int* parr = new int[10];
delete[] parr;
        申请和释放单个元素的空间,使用 new delete 操作符,申请和释放连续的空间,使用 new[] delete[] ,注意:匹配起来使用

📁 new 和 delete的优点

        上文中,我们已经知道了new 和 delete 操作符的部分优点:

1. 编译器会自动检查内存空间是否成功开辟,如果失败,则会抛异常。

2. 可以完成初始化的工作。对于自定义类型,会调用它的构造函数和析构函数。

int* pa = new int(1);//如果是不完全初始化,后面会用0代替。
int* parr = new int(10){1,2,3,4,5};

📁 new 和 delete的原理

        以上我们简单了解了new和delete操作符的基本使用,想要彻底掌握,我们就从底层了解new和delete的区别以及底层实现。

 📂 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 bytes
void *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来申请空间,如果malloc申请成功直接返回(原地扩容),否则执行用户提供的空间不足的措施(异地扩容),如果用户提供改措施,则会继续申请,否则抛异常。

         operator delete 最终通过free来释放空间。

 📂 内置类型

        如果申请的是内置类型的空间(int , double,指针...),new和malloc ,delete和free基本类似,不同之处在于:new 和 delete 是申请和释放单个元素空间,new[]和delete[]申请的是连续空间,释放连续的空间。而且new申请空间时会抛异常,malloc则会返回NULL。

 📂 自定义类型

        ● new的原理

        1. 调用operator new函数申请空间。

        2. 在申请的空间上执行构造函数,完成对象的构造。

        ● delete的原理

        1. 在空间上进行析构函数,完成对象资源的清理工作。

        2. 调用operator delete函数释放对象空间。

        ● new[ ]的原理 

        1. 调用operator new[ ]函数,在operator new[ ]中实际调用operator new函数完成 N个对象空间的申请。

        2. 在申请空间上调用N次构造函数。

        ● delete[ ]的原理

        1. 在释放对象的空间上进行N次析构函数,完成N个对象中资源的清理。

        2. 调用operator delete[ ]释放资源,实际在operator delete[ ]中调用operator delete[ ]了释放空间。

📁 内存泄漏

        什么是内存泄漏:内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。
        内存泄漏的危害:长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现内存泄漏会导致响应越来越慢,最终卡死。

        

📁 总结

        以上,就是本期【C++杂货铺】内存管理的主要内容了,主要介绍了new和delete操作符的使用,有点及其底层原理。

        此外,简单介绍了C/C++中内存分布情况,以及内存泄露的基本概念和危害。

        如果感觉本期内容对你有帮助,欢迎点赞,收藏,关注Thanks♪(・ω・)ノ

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小狐狸JSON-RPC:wallet_addEthereumChain(添加指定链)

wallet_addethereumchain(添加网络) var res await window.ethereum.request({"method": "wallet_addEthereumChain","params": [{"chainId": "0x64", // 链 ID (必填)"…

职场沟通教训 程序汪改了一行代码,导致测试和开发大战

本文章有视频的,请到B站 我是程序汪 观看 程序汪改了一行代码,导致测试和开发大战,职场沟通教训 程序汪改了一行代码,导致测试和开发大战 鸡汤文 每个人都会在沟通上出问题 工作上沟通出问题可能让你郁闷一天、丢了客户、损失金…

机器学习作业二之KNN算法

KNN(K- Nearest Neighbor)法即K最邻近法,最初由 Cover和Hart于1968年提出,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一。该方法的思路非常简单直观:如果一个样本在特征空间中的K个最相似&…

每日一题 --- 快乐数[力扣][Go]

快乐数 题目:202. 快乐数 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为: 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到…

GitLab更新失败(Ubuntu)

在Ubuntu下使用apt更新gitlab报错如下: An error occurred during the signature verification.The repository is not updated and the previous index files will be used.GPG error: ... Failed to fetch https://packages.gitlab.com/gitlab/gitlab-ee/ubuntu/d…

揭秘百度百科审核内幕,百科词条审核究竟需要多久?

百度百科作为国内最大的网络百科全书平台之一,致力于提供全面、准确的知识服务,同时也承担着审核百科词条的工作。在互联网时代,人们对信息的需求日益增长,因此百度百科的审核工作显得尤为重要。那么,百度百科词条审核…

Codigger用户篇:安全、稳定、高效的运行环境(二)

在当今数字化时代,随着云计算和大数据技术的飞速发展,分布式操作系统已成为支撑各类应用高效运行的关键基础设施。我们推出的Codigger分布式操作系统,正是为了满足用户对安全、稳定、高效私人应用运行环境的需求而精心设计的。上一次&#xf…

【大数据运维】minio 常见shell操作

文章目录 1. 安装2. 入门操作3. 命令帮助 1. 安装 下载 https://dl.min.io/client/mc/release/linux-amd64/ 赋权与使用 cp mc /usr/bin && chmod x /usr/bin/mc ./mc --help 2. 入门操作 # 添加minio到mc mc config host add minio_alias_name endpoint_adress …

素材投放效果追踪与精准识别:从数据洞察到策略优化的全方位解析

一、数据洞察:深度解析投放效果的核心指标在数字广告的世界里,数据是投放效果的晴雨表。通过深入的数据洞察,广告主可以清晰地掌握广告的实际表现,为后续的策略调整提供有力的支持。曝光量、点击率、转化率和投资回报率等指标&…

租用2核8G云服务器优惠价格258元一年、998元3年

京东云2核8G服务器优惠价格258元一年、998元三年,配置为2C8G-80G SSD系统盘-3M带宽-200G月流量 华北-北京,京东云服务器优惠活动页面 atengyun.com/go/jd 京东云2核8G服务器优惠价格 京东云:轻量云主机CPU内存:2C8G公网带宽&#…

Java基础之算数运算符的初级用法

运算符 运算符: 对字面量或者变量进行操作的符号 表达式: 用运算符把字面量或者变量连接起来,符合java语法的式子就可以称为表达式 不同运算符连接的表达式体现的是不同类型的表达式 一 .算数运算符 实践一下 加 减 乘 运行结果: 除 取模 运行结果 练习: 数值拆分 需求…

Windows Server 2022 使用ApacheDS用户远程桌面登录服务器

Windows Server 2022 使用ApacheDS用户远程桌面登录服务器 1、接上篇 Windows Server 2022 使用ApacheDS用户认证 使用Administrator用户远程登录192.168.1.100windows server,打开pGina软件 2、输入刚刚在ApacheDS中的新添加的用户测试一下,会自动添加…