C++---内存管理

news2024/11/14 13:32:00

1 C/C++内存分布

栈区:由编译器自动分配和释放,存放运行时候的局部变量,函数参数,返回数据,返回地址。

堆区:一般由程序员自己分配,然后自己释放,例如栈的实现malloc开辟的数组空间。

数据段(静态区):存放全局变量,静态数据,常量,程序结束后自动释放。

代码段(常量区):存放常量字符串和可执行代码,程序结束自动释放。

2 C语言中动态内存管理方式:malloc/calloc/realloc/free

malloc:开辟空间,不初始化 (int*)malloc(sizeof(int)):开辟一个int大小的空间。

calloc:开辟空间并把每个字节初始化为0。(int*)calloc(4,sizeof(int)):开辟4个int大小的空间。

realloc(用于扩容):在内存找一段连续大小的空间,将传入的指针指向的内存内的字节全部拷贝过来,然后释放原指针空间,再把新大小的空间指针返回。(int*)realloc(_ptr,sizeof(int)*10)。

free:释放一段连续空间。free(_ptr),释放完之和_ptr为野指针,一般需要_ptr=NULL。

3 C++内存管理实现

C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。

在对内置类型开辟空间时new和malloc实质上是没什么区别的,但在对自定义类对象进行空间开辟时候,new和malloc的区别在于malloc只负责开辟空间不会进行初始化,而new开辟空间的同时会调用自定义类内的构造函数进行初始化。

 

注意:申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[]和delete[],注意:匹配起来使用。

new/delete和malloc/free最大的区别在于,new/delete开辟空间会调用构造函数,结束会调用析构函数。而malloc/free不会。

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_FINALLY
    return;
}
/*
free的实现
*/
#define free(p) _free_dbg(p, _NORMAL_BLOCK)

通过上述两个全局函数的实现知道,operator new 实际也是通过malloc来申请空间,如果malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的。

说白了operator new就是new子过程,new就等价于operator new之和在调用构造函数。而operator new在程序设计上又是由malloc为基础,区别于malloc的就是malloc申请空间失败之和返回值是0。而operator new申请空间失败后是直接抛异常。

定位new表达式

定位new表达式在实际中一般是配合内存池使用。因为内存池分配出的内存没有初始化,所以如果是自定义类型的对象,需要使用new的定义表达式进行显示调构造函数进行初始化。

我们用malloc为p3开辟一个结构体大小的空间后,成员变量并没有初始化,但由于成员变量为private修饰的在外不可访问,这时候就可以利用定位new去进行初始化。

定位new格式为new(变量)+类名(初始化)。

malloc/free与new/delete的区别

共同点是都在堆上申请空间,需要用户手动释放。

区别是malloc/free是函数而new/delete是操作符。

malloc/free使用时候只开辟空间和销毁空间,而new/delete开辟空间会调用构造函数初始化,销毁空间会调用析构函数。

malloc返回值是void*使用时候需要强转类型,而new不用,编译器自动识别。

malloc申请空间失败返回的是NULL,而new申请空间失败会抛异常。

内存泄露

什么是内存泄漏:内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。 

内存泄漏的危害:长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现内存泄漏会导致响应越来越慢,最终卡死。

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

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

相关文章

尝试开发油猴(Tampermonkey)脚本

篡改猴 (Tampermonkey) 是拥有 超过 1000 万用户 的最流行的浏览器扩展之一。 它适用于 Chrome、Microsoft Edge、Safari、Opera Next 和 Firefox。 有些人也会把篡改猴(Tampermonkey)称作油猴(Greasemonkey),尽管后者只是一款仅适用于 Firefox 浏览器的浏览器扩展…

UE5 Linux编译流程(实战)

文章目录 概述setup.sh2.GenerateProjectFiles.sh3.make其他的 小结 概述 之前写过一篇linux上代码的流程,这一篇,补下编译流程。4.26还是4.27的时候,做过编译,那会刚出来,当时编译用的是QT,跟着文档&…

传输大咖40 | 医药行业跨国文件传输的挑战与解决方案

在当今全球化浪潮的推动下,医药健康领域的国际合作变得越发密切。无论是共享临床试验的数据,还是协作推进新药的研发,一个高效的文件传输系统都显得尤为关键,它直接关系到整个行业的快速进步。但是,当文件跨越国界进行…

Redis缓存击穿、缓存穿透、缓存雪崩场景描述及解决方案

Redis缓存击穿、缓存穿透、缓存雪崩场景描述及解决方案 缓存穿透 用户请求了很多既不存在于redis也不存在于数据库的无效数据请求,导致redis无法拦截,最终所有请求都落在数据库中 解决方案:缓存空对象(会导致redis中存了很多垃…

The Magic Loop-快速职业发展的框架

前言 在 B2B 系列中短暂休息一下,我很高兴为你带来 Ethan Evans 的重要客座文章。在 Amazon 的 15 年里,Ethan 帮助发明了 Prime Video、Amazon Video、Amazon Appstore、Prime Gaming(以前称为 Twitch Prime)和 Twitch Commerce…

电阻器件选型

电阻参数 一般都是(前面数字x10^末尾数字),如下面的例子 大概清楚电阻的结构即可,无需掌握 电阻器安装在陶瓷基板的上面;在每一端都有内部金属电极,使其与厚膜电阻体接触;电阻原件的成分是金…

第144天:内网安全-Linux权限维持OpenSSHPAM后门SSH软链接公私钥登录

目录 案例一: 权限维持-Linux-替换版本-OpenSSH 后门 案例二: 权限维持-Linux-更改验证-SSH-PAM 后门 案例三: 权限维持-Linux-登录方式-软链接&公私钥&新帐号 ssh软链接 公私钥 新帐号 案例一: 权限维持-Linux-替换…

一. Unity实现虚拟摇杆及屏幕自适应功能

手游里面很多类型的游戏都需要用到遥感功能,例如王者荣耀,和平精英等,之前的摇杆功能都是用类似于Easy Touch的插件进行开发的,今天不借助任何插件来实现虚拟摇杆的功能。 一般虚拟摇杆的组成都是由轮盘和遥感的点组成&#xff0c…

二百六十二、Java——打开别人项目时缺少maven配置,无法运行文件

一、目的 在打开别人的项目时,发现Java文件类型显示出错,没有application,无法运行文件 二、报错原因 项目缺少maven配置 三、解决措施 File——Setting——Maven 修改Maven的配置,指向Maven路径 四、重启项目 文件恢复正常…

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(wa…

跨境外贸业务使用新加坡裸机云站群服务器优势

在全球化的今天,跨境外贸业务正变得越来越普遍。随着互联网技术的发展,越来越多的企业选择使用云计算服务来支持其国际业务。新加坡作为一个国际金融中心和亚洲的数据枢纽,提供了优质的网络基础设施,使其成为设置裸机云站群服务器…

【vue3|第28期】 Vue3 + Vue Router:探索路由重定向的使用与作用

日期:2024年9月8日 作者:Commas 签名:(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释:如果您觉在这里插入代码片得有所帮助,帮忙点个赞,也可以关注我,我们一起成长;如果有不对…

第18届世界杰出华人奖得主王傲山:承父业展关怀,体现“圆桌”精神

王傲山博士是“保二代”,由父亲言传身教及自孩提时代刻在骨子里的氛围,让他理所当然地传承父亲保险助人为乐的精神。在保险行业打滚两旬余,他成就多项傲人的成绩、取得个人成就的同时,以更高的指标作为团队精神,秉持追…

苹果手机qq原文件失效怎么恢复?4个方法,让失效变有效!

热门提问:在QQ上的文件忘记下载了,文件已经过期且无法打开,有什么方法可以恢复这些失效的文件呢? 小编这里有4个靠谱的方法,可以解决苹果手机QQ原文件失效怎么恢复的问题。只要大家掌握了这4个方法,让苹果…

【如何在鼠标右键添加Typora软件(使用脚本)】

下载Typora后,希望右键新建文件时候,可以新建md文件。 使用下面的注册脚本就可以实现: Windows Registry Editor Version 5.00[HKEY_CLASSES_ROOT\.md] "Typora.md" "Content Type""text/markdown" "Per…

C语言---函数指针基础总结万字(4)

一、 函数 1.函数是一段可以重复执行的代码。 它可以接受不同的参数, 完成对应的操作。 下面的例子就是一个函数 int plus(int n) {return n; }上面的代码声明了一个函数plus()。 2.函数声明的语法有以下几点,需要注意。 返回值类型。 函数声明时&a…

Mac电脑IDEA2024安装后打不开问题解决

Mac电脑IDEA2024安装后打不开问题解决 由于电脑系统升级,导致我用的2019版本的IDEA一打开就卡,机缘巧合拥有了一个正版的IDEA账号,下载2024版本的IDEA,打开报错。 由于电脑系统升级,导致我用的2019版本的IDEA一打开就卡…

Day20_0.1基础学习MATLAB学习小技巧总结(20)——MATLAB绘图篇(3)

利用空闲时间把碎片化的MATLAB知识重新系统的学习一遍,为了在这个过程中加深印象,也为了能够有所足迹,我会把自己的学习总结发在专栏中,以便学习交流。 参考书目:《MATLAB基础教程 (第三版) (薛山)》 之前的章节都是…

项目实战系列三: 家居购项目 第五部分

&#x1f333;显示订单[订单管理] &#x1f333;暂时缺货 需求分析 1.如果某家居库存为0, 首页的"Add to Cart" 按钮显示为"暂时缺货" 2.后台也加上校验. 只有在 库存>0 时, 才能添加到购物车 代码实现 1.修改web/views/customer/index.jsp <c:if…

网络层 VIII(网络层设备——路由器)【★★★★★★】

一、冲突域与广播域 这里的“域”表示冲突或广播在其中发生并传播的区域。 1. 冲突域 冲突域是指连接到同一物理介质上的所有结点的集合&#xff0c;这些结点之间存在介质争用的现象&#xff08;能产生冲突的所有设备的集合&#xff09;。也就是说&#xff0c;若这些设备同时发…