【C++】内存管理:内存分布,new/delete的使用及细节处理,new/delete的底层,定位new表达式

发布时间:2026/7/15 6:08:39
【C++】内存管理:内存分布,new/delete的使用及细节处理,new/delete的底层,定位new表达式 ‍博主名称鱼子星_✅数据结构专栏【数据结构】✅算法竞赛专栏【算法竞赛】✅C系列专栏【C从零开始系列】前言在 C/C 编程中动态内存管理是构建高效、灵活程序的核心技能之一。从 C 语言的malloc/free到 C 的new/delete看似简单的内存申请与释放背后隐藏着语言设计哲学、对象生命周期管理以及底层内存机制的深刻差异。本文旨在系统性地剖析 C 动态内存管理的全貌。我们将从内存分布的基础知识出发逐步对比 C 与 C 的动态内存开辟方式深入探讨new/delete对内置类型与自定义类型的处理机制、其底层实现原理operator new/operator delete并拓展至定位new表达式等高级话题。通过清晰的代码示例、内存布局图解和面试题解析帮助你不仅掌握语法更理解其设计意图与适用场景从而在项目中做出更优雅、更安全的内存管理决策。无论你是正在巩固基础的初学者还是希望深入理解 C 对象模型的中级开发者相信本文都能为你提供清晰的指引和实用的参考。一. 内存分布在对C内存分布了解前先来看如下的题目intglobalVar1;staticintstaticGlobalVar1;voidTest(){staticintstaticVar1;intlocalVar1;intnum1[10]{1,2,3,4};charchar2[]abcd;constchar*pChar3abcd;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);}一.选择题 选项: A.栈 B.堆 C.数据段(静态区) D.代码段(常量区) 1.globalVar在哪里__C__ 2.staticGlobalVar在哪里__C__ 3.staticVar在哪里__C__ 4.localVar在哪里__A__ 5.num1 在哪里__A__ 6.char2在哪里__A__ 7.*char2在哪里__A__ 8.pChar3在哪里__A__ 9.*pChar3在哪里__D__ 10.ptr1在哪里__A__ 11.*ptr1在哪里__B__题目解析globalVar是全局变量生命周期持续到程序结束所以内存在静态区staticGlobalVar本身就是全局变量再加上static也还是在静态区staticVar被static修饰内存在静态区localVar局部变量的内存都在栈上num1也属于局部变量char2是局部字符数组的变量名内存在栈上*char2看似是静态的字符串abcd但是它的内存还是在栈上有如下 2 种理解方式*char2是常量区中的abcd的拷贝abcd是局部域的数组的元素当函数结束时函数内部的数据会随着栈帧销毁所以*char2在栈上pChar3也在栈上因为 const 修饰的并不是pChar3而是*pChar3*pChar3被 const 修饰在常量区ptr1知识局部域的一个指针变量在栈上*ptr1是动态申请的内存内存在堆上测试验证内存空间在C中有如下几种内存空间存储着不同属性的数据栈堆栈存储着非静态局部变量/函数参数/返回值。栈的空间是自顶向下延伸的堆动态申请的空间都在堆上数据段静态区存储全局数据和静态数据代码段常量区存储只读常量二. C语言中动态内存开辟的方法动态内存开辟malloc/calloc/realloc//1.malloc/calloc/realloc的区别是什么int*p1(int*)malloc(sizeof(int)*10);int*p2(int*)realloc(p1,sizeof(int)*20);free(p2);面试题分析malloc/calloc/realloc和区别是什么malloc只能用于动态内存开辟对开辟的空间不能初始化calloc可以对动态开辟的空间初始化realloc用于对已有的空间扩容扩容有两种情况原地扩容和拷贝数据到另外的地方扩容malloc的实现原理是什么感兴趣的可以点击这个链接查看【CTF】GLibc堆利用入门-机制介绍三. C中动态内存开辟的方法1. new/delete的语法使用C中一般使用关键字new和delete进行动态内存开辟对于单个元素的内存开辟其使用的格式为类型*变量名new类型(初始化的值);//初始化的值可以写也可以不写delete变量名;如果要申请一块连续的动态内存开辟时在类型之后使用[size]来定义开辟的大小size为需要申请的元素个数释放内存时在delete后加上[]定义格式为类型*变量名new类型[size];//初始化的方式和数组相同delete[]变量名;️ 使用关键字 new 动态开辟内存时返回值不需要使用类型转换new会自行匹配返回值的类型2. new/delete动态申请内置类型对于内置类型的动态开辟new/delete和malloc/free的功能并没有很大的差别除了使用更加方便外new主要的优势就是动态开辟内存时可以顺便初始化。//使用new动态开辟内存int*p1newint(10);//直接将*p1初始化成了10int*arr1newint[10]{1,2,3};deletep1;delete[]arr1;//使用malloc动态开辟内存int*p2(int*)malloc(sizeof(int));*p210;int*arr2(int*)malloc(sizeof(int)*10);free(p2);free(arr2);使用new直接初始化使用malloc不能直接初始化3. new/delete动态申请自定义类型使用new和delete对自定义类型进行动态内存开辟对比使用malloc和free有一个绝对的优势就是使用new进行动态内存开辟会自动调用自定义类型的默认构造函数使用delete释放内存会自动调用自定义类型的析构函数#includeiostreamusingnamespacestd;classA{public:A(inta1):_a(a){coutA(int a 1)endl;}~A(){_a0;cout~A()endl;}private:int_a;};intmain(){A*pnewA;deletep;return0;}使用上代码可以进行验证输出结果为如果使用new和delete进行多个元素的动态内存申请和销毁编译器会相应的调用多次构造函数和析构函数为什么这里又说new会调用构造函数呢其实上面已经说了使用new进行动态内存开辟可以直接初始化这个方法也适用于自定义类型。那要如何进行初始化呢这就需要看自定义类型中写的构造函数有多少种样子了只要有相应的构造函数那么用什么样的初始化方式都没问题这里针对有意义的初始化。所以这里其实也可以得出使用new对自定义类型进行动态内存开辟的初始化是根据初始化的形式调用构造函数的如果没有显式的初始化就会调用默认构造函数反之会调用参数最适合的构造函数。️ 如果是对多个元素每个元素都有多参数的初始化的动态内存开辟每组参数需要使用{}括起来A*pnewA[3]{{1,2},{3,4},{4,5}};classA{public:A(inta1):_a(a){coutA(int a 1)endl;}A(inta1,inta2):_a(a1a2){coutA(int a1, int a2)endl;}~A(){_a0;cout~A()endl;}private:int_a;};intmain(){A*p1newA(10);A*p2newA(10,10);deletep1;deletep2;return0;}️ 输出-小结使用malloc动态内存分配不能对申请的空间进行初始化使用new可以使用new/delete在内存申请时会自动调用构造函数在内存释放时会调用析构函数new对自定义类型的空间初始化会根据初始化的方式选择合适的构造函数例如没有显式传参就调用默认构造如果有就会对照初始化的参数选择最合适的构造函数️ 如果自定义类型没有默认构造则使用new一定要显式的初始化4. new/delete的使用场景我们使用malloc/free对链表类进行动态内存分配时初始化需要手动写一个Init函数进行初始化而对于链表自身申请的空间还需要手动的调用析构函数来释放内存这样操作很不方便classList{public:List(intn4){_arr(int*)malloc(sizeof(int)*n);_capacity4;_size0;}~List(){if(_arr){free(_arr);_arrnullptr;}_capacity_size0;}voidInit(intn4){_arr(int*)malloc(sizeof(int)*n);_capacity4;_size0;}private:int*_arr;int_capacity;int_size;};intmain(){//无法初始化List*lt(List*)malloc(sizeof(List));(*lt).Init();//手动调用析构函数(*lt).~List();free(lt);return0;}而如果使用new/delete进行动态内存申请它们会自动的调用 List 的构造函数和析构函数这也就代表使用 new 不仅会申请lt指针的内存更会调用 List 的构造函数将链表初始时的内存也申请了使用 delete 释放空间不仅仅是释放lt指针的内存更会先调用 List 的析构函数释放链表动态申请的空间可谓事半功倍//自动调用构造函数List*ltnewList;//自动调用析构函数deletelt;️ 这里还有一点需要注意new 是先申请空间再调用构造函数delete 是先调用析构函数再释放指针的空间5. 【拓展】new和delete的配套使用new和delete一定要配套使用使用new申请内存空间就一定要使用delete释放内存空间。为什么来看下面一段代码A*pnewA[10];delete[]p;已知一个A类型的大小为 4 字节所以这里申请 10 个A类型的空间空间大小应该为 40 个字节。那这里真的是 40 个字节吗其实不是的这里在x86的环境下调试会发现这里申请了 44 个字节。那new多申请这 4 个字节的空间用来干什么其实是为了保存一共这块空间一共申请了多少个A类型的对象有的人会问保存这个干什么那如果没有保存这个数值编译器要怎么确定释放空间时需要调用多少次析构函数呢既然这多出来的 4 个字节是存储对象个数的那么这个空间的数值应该是 10我们可以使用内存窗口查看。所以这里就知道了当使用new申请多个对象的内存时它会在原本的空间前面多申请一个内存空间用来存储申请的对象的个数这里回到刚才的问题现在你或许就已经知道为什么new和delete需要配套使用了。小结由于new一次申请多个对象的空间会在空间前面多申请一个内存空间而如果使用free来释放空间它并不会将前面多申请的内存空间释放这样就会导致程序运行崩溃因此使用new申请的空间内存应该使用delete释放。️ 使用new[]申请多个对象时仅仅使用delete释放内存程序也会崩溃正确的是使用对应的delete[]四. operator new和operator delete函数1. new的底层——operator new函数在感叹new为何如此方便之时我们不禁问到new这么好用那它的底层是不是很复杂呢这里先说结论new的底层是operator new函数operator new 并不存在于标准库中而是一个全局函数我们可以通过C参考手册确定关于 operator new 函数的具体细节这里不过多赘述而是主要看 new 的底层实现这里可以通过调试的反汇编观察 new 的底层//自动调用构造函数List*ltnewList;//自动调用析构函数deletelt;继续进入 operator new 的函数的实现惊奇的发现operator new 的底层居然是malloc函数我们再来理清楚调用逻辑当使用 new 动态内存申请时new 会调用 operator new 函数而 operator new 函数本质上又还是通过 malloc 申请动态内存所以 new 的本质还是使用 malloc 动态申请内存。️ 使用 new 申请空间时构造函数的调用并不是封装在operator new函数的而是分开的。其实从刚刚的第一层反汇编就可以看到2. delete的底层——operator delete函数delete 的底层和 new 一样都是通过调用其他的函数实现的delete 对应的函数为operator delete追溯到最底层会发现delete 释放空间的功能是通过free实现的。这里也还同时验证了上面所说delete 是先调用析构函数再调用 operator delete 释放指针的内存的。小结new 是通过调用 operator new 申请空间的而 operator new 又是使用malloc 申请空间的所以本质上 new 还是使用 malloc 申请空间delete 是通过 operator delete 释放空间的本质上它还是使用free释放空间operator new 和 operator delete 都是全局函数五. 定位new表达式(placement-new)定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象其使用格式如下new(ptr)type;注 ptr是指向内存空间的指针 type是要调用的拷贝构造对应的类型定位 new 表达式一般是搭配内存池的使用这里在之后的篇章会讲解classA{public:A(inta1):_a(a){coutA(int a 1)endl;}~A(){_a0;cout~A()endl;}private:int_a;};intmain(){A*p(A*)malloc(sizeof(A));new(p)A;p-~A();free(p);//使用 operator new和malloc效果一样A*p1(A*)operatornew(sizeof(A));new(p1)A;p1-~A();operatordelete(p1);return0;}️ operator new 本质上也是调用malloc申请内存空间所以它的使用方式也和 malloc一样需要强制类型转换和以字节为单位开辟空间否则编译器会报错六. new/delete和malloc/free的区别语法区别new/delete不需要使用强制类型转换malloc/free需要new/delete申请空间不需要判断空指针malloc/free需要new/delete给多个元素申请空间不需要计算空间大小malloc/free需要new/delete可以在申请空间后直接初始化malloc/free不可以️ 这里说到使用new申请空间不需要判断空指针是因为new空间申请失败时会抛出异常使用catch接收异常就知道空间申请失败了。这里new抛异常在之后的篇章会讲解核心区别new/delete对自定义类型的内存申请和内存释放会自动调用对应的构造函数和析构函数malloc/free则没有这个功能本篇完结下期预告【C】string上

相关新闻

h5商城网站怎么建设?别踩坑,这才是普通人能看懂的避坑指南

h5商城网站怎么建设?别踩坑,这才是普通人能看懂的避坑指南

最近好多朋友问我,h5商城网站怎么建设才不亏钱?说实话,这行水挺深。很多人一上来就找外包,报价几千到几万不等。你以为捡了便宜,其实后面全是雷。我见过太多老板,花了两万块做个模板。结果打开速度慢得像蜗牛,用户看一眼就跑了。这钱花得,真不如请客吃饭实在。咱们今天…

发布时间:2026/7/15 6:07:35
积极推进政务网站建设,别让“指尖上的形式主义”毁了公信力

积极推进政务网站建设,别让“指尖上的形式主义”毁了公信力

打开政府网站,满屏的广告弹窗和打不开的链接,是不是让你瞬间想关掉?别急,这篇干货直接教你怎么避开那些坑,让网站真正好用,而不是用来“看”的。只要改对这三点,你的政务号就能从“摆设”变成“神器”。说真的,我受够了那些看起来高大上,用起来却像迷宫一样的政务平台…

发布时间:2026/7/15 6:07:10
网站建设部分费用会计科目怎么入账才不踩坑?老会计的掏心窝子分享

网站建设部分费用会计科目怎么入账才不踩坑?老会计的掏心窝子分享

做财务这行久了,你会发现很多看似简单的业务,一碰到细节就让人头大。特别是最近有个新手会计妹子问我,公司花了几万块搞了个官网,这钱到底该怎么记?是进固定资产还是管理费用?当时我差点脱口而出“看金额”,但话到嘴边又咽了回去,因为事情没那么简单。今天咱们就掰开了…

发布时间:2026/7/15 6:05:55
江苏兴力建设集团有限公司网站怎么查资质?老包工头含泪避坑指南

江苏兴力建设集团有限公司网站怎么查资质?老包工头含泪避坑指南

找施工队怕被坑?怕遇到皮包公司卷款跑路?怕工程质量烂尾还找不到人?这篇干货直接教你怎么通过官方渠道核实施工方底细,别再让血汗钱打水漂。干工程这么多年,见过太多因为轻信口头承诺而栽跟头的老板。很多人觉得找个熟人介绍或者看个样板房就万事大吉,结果后期增项无数,…

发布时间:2026/7/15 7:12:01
别被忽悠了,网站建设方案实施到底是个什么坑?

别被忽悠了,网站建设方案实施到底是个什么坑?

上周二半夜两点,我盯着电脑屏幕,手里那杯咖啡早就凉透了,像极了我现在的心情。对面坐着的客户老张,眉头皱得能夹死蚊子,他问我:“你们不是说好三天上线吗?怎么后台连个登录入口都找不到?”我张了张嘴,想解释那是服务器配置延迟,但话到嘴边又咽了回去。因为我知道,这…

发布时间:2026/7/15 7:11:57
别瞎忙了!广东省建设交易中心网站这点猫腻,搞不懂真亏大

别瞎忙了!广东省建设交易中心网站这点猫腻,搞不懂真亏大

说实话,干咱们这行,最烦的就是那种装模作样的官腔。尤其是跟招投标打交道的时候,心里那叫一个堵得慌。今天咱们不聊虚的,就聊聊那个让无数老板头秃的地方——广东省建设交易中心网站。很多人觉得,这就个挂公告的地方,上去看看有没有新活儿,完事儿。大错特错!我有个朋友…

发布时间:2026/7/15 7:10:09
怀来住房和城乡建设局网站查不到政策?别慌,老房主教你怎么避坑

怀来住房和城乡建设局网站查不到政策?别慌,老房主教你怎么避坑

本文关键词:怀来住房和城乡建设局网站说真的,每次听到有人在那儿抱怨“办事难”、“找不着门”,我心里就堵得慌。尤其是咱们怀来这地界,搞装修的、想买房的、甚至就是家里老房子漏雨想问问能不能申请补贴的,大伙儿第一反应往往是跑大厅。跑大厅好啊,态度好,但架不住人多…

发布时间:2026/7/15 7:09:59
去鹤岗买房前必看,黑龙江省鹤岗市城乡建设局网站怎么查违建

去鹤岗买房前必看,黑龙江省鹤岗市城乡建设局网站怎么查违建

说句掏心窝子的话,很多人盯着鹤岗几万块的房子,觉得是捡漏。但我得给你泼盆冷水。这地方水很深,不是谁都能随便进的。我有个朋友,去年脑子一热,没做背调就签了合同。结果房子被查封,钱退不回来,人找不着。那种绝望,真的会让人整宿整宿睡不着觉。所以,今天我不讲大道理…

发布时间:2026/7/15 7:09:50
山东省住房和城乡建设厅网站电话打不通?别急,这招最管用

山东省住房和城乡建设厅网站电话打不通?别急,这招最管用

最近好多朋友在后台问我,说想咨询个建筑资质的事儿,或者查查某个项目的审批进度。结果一搜“山东省住房和城乡建设厅网站电话”,要么占线,要么打过去是个空号,急得跟热锅上的蚂蚁似的。我也试过,真的,那电话有时候就是难打。为啥?因为找的人太多了。大家伙儿都急着办事…

发布时间:2026/7/15 7:09:38
nRF Sniffer 在Wireshark中的高效过滤与实战技巧

nRF Sniffer 在Wireshark中的高效过滤与实战技巧

1. 初识nRF Sniffer与Wireshark黄金组合当你第一次把nRF52840 Dongle插入电脑时,可能没想到这个小玩意儿会成为BLE调试的"显微镜"。作为专为蓝牙低功耗设计的嗅探工具,nRF Sniffer配合Wireshark就像给开发者装上了X光眼镜,能清晰看…

发布时间:2026/7/15 0:00:38
别被忽悠了,普通人怎么选择五屏网站建设才不踩坑

别被忽悠了,普通人怎么选择五屏网站建设才不踩坑

前年我接手公司官网改版,当时脑子一热,觉得搞个“五屏自适应”听起来特别高大上。结果呢?上线第一周,客服电话被打爆,全是客户说手机上看图糊成马赛克,按钮还点不动。那几天我头发都愁白了,找技术对线,找设计扯皮,最后发现全是沟通不到位留下的坑。今天就把我踩过的雷…

发布时间:2026/7/15 0:00:52
泰州网站建设案例揭秘:从0到1的避坑指南与实战心得

泰州网站建设案例揭秘:从0到1的避坑指南与实战心得

泰州网站建设案例 你是否还在为网站打开速度慢而焦虑?是否因为转化率低下而怀疑自己的产品?这篇内容直接给你答案。我不讲虚的理论,只讲怎么把网站做成赚钱机器。做网站最怕什么?怕像绣花枕头,中看不中用。我见过太多泰州的企业老板,花了几万块做个高大上的首页。结果用户…

发布时间:2026/7/15 0:00:52
别装了,你的学院网站建设推进会就是场大型尴尬现场

别装了,你的学院网站建设推进会就是场大型尴尬现场

看着后台那点可怜的访问量,你急不急?方案改了八版,还是没人看。今天这文,只说怎么把会开成,把事做成。上周去隔壁职院蹭会,那场面,真叫一个窒息。会议室里坐满了人,领导在台上讲PPT,底下的人不是在玩手机,就是在发呆。投影仪闪了两下,灭了。没人去修,接着讲。这种会…

发布时间:2026/7/14 8:24:42
七彩建设集团官方网站怎么找?避坑指南与真实体验分享

七彩建设集团官方网站怎么找?避坑指南与真实体验分享

找官网找得头大?这篇直接告诉你怎么辨别真伪,别被假网站坑了钱。昨天半夜两点,我还在电脑前盯着屏幕,心里那个急啊。家里装修刚进场,工长突然说需要确认一份材料清单,说是七彩建设那边要求的。我手忙脚乱地打开浏览器,搜了一堆“七彩建设”,结果出来一堆广告,什么“七…

发布时间:2026/7/14 2:42:40
找可信赖的龙岗网站建设公司?别踩坑,看这几点就够

找可信赖的龙岗网站建设公司?别踩坑,看这几点就够

做企业,网站就是脸面。 在龙岗,想找个靠谱的网站公司,真不容易。 市面上广告满天飞。 承诺得天花乱坠。 最后交付的东西,却让人想砸电脑。 今天不聊虚的。 只聊怎么避坑。 怎么找到真正可信赖的龙岗网站建设团队。先说个大实话。 别信什么“三天上线”。 那是骗小白的。 正…

发布时间:2026/7/14 19:05:38
建站7年才悟出的网站建设思路,别再花冤枉钱了

建站7年才悟出的网站建设思路,别再花冤枉钱了

做建站这行整整7年了。 见过太多老板花几万块, 最后做出来的网站像个垃圾场。 今天不整那些虚头巴脑的术语。 就聊聊我踩过的坑, 和真正能落地的网站建设思路。很多老板一上来就问: “多少钱能做个高大上的?” 我通常直接劝退。 因为方向错了, 你给再多钱也是打水漂。 真正…

发布时间:2026/7/14 13:09:53
合肥的网站建设避坑指南:别被低价忽悠,这3个细节决定生死

合肥的网站建设避坑指南:别被低价忽悠,这3个细节决定生死

做企业官网最怕什么?不是技术难,是交钱后没人管,或者上线一个月连个访客都没有。这篇东西不扯虚的,直接告诉你怎么在合肥找个靠谱的团队,或者自己怎么避坑。先说个大实话,我在合肥混这行五年多,见过太多老板因为贪便宜吃大亏。你去百度搜“合肥的网站建设”,出来一堆报…

发布时间:2026/7/15 2:07:05
别被忽悠了!德州网站建设那些坑,我拿真金白银换来的教训

别被忽悠了!德州网站建设那些坑,我拿真金白银换来的教训

做这行久了,心里就憋着一股火。每次看到客户拿着网上抄来的模板,问我能不能做成“苹果官网”那种效果。我就想笑。真的,太想笑了。今天咱不整那些虚头巴脑的专业术语。就聊聊德州网站建设里,那些让人头秃的真实事儿。我有个客户,老张。他是做德州本地建材的,实在人。当初…

发布时间:2026/7/15 2:07:13