C/C++内存管理:从内存布局到malloc/free 与 new/delete 的深度解析

c/cpp程序内存区域划分

  1. 栈(Stack)
    • 存储非静态局部变量、函数参数、返回值
    • 向下增长(从高地址向低地址)
    • 自动分配和释放
  2. 堆(Heap)
    • 动态内存分配区域
    • 向上增长(从低地址向高地址)
    • 手动管理(malloc/free, new/delete)
  3. 数据段/静态区
    • 存储全局变量和静态变量
    • 程序开始时分配,结束时释放
  4. 代码段/常量区
    • 存储可执行代码和字符串常量
    • 只读区域
  5. 内存映射段
    • 文件映射、动态库、匿名映射
    • 进程间通信

练习

intglobalVar=1;// 数据段staticintstaticGlobalVar=1;// 数据段voidTest(){staticintstaticVar=1;// 数据段intlocalVar=1;// 栈intnum1[10]={1,2,3,4};// 栈charchar2[]="abcd";// 栈constchar*pChar3="abcd";// 指针在栈,字符串在代码段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.代码段(常量区)-`globalVar`在哪里?__->C(数据段)-`staticGlobalVar`在哪里?__->C(数据段)-`staticVar`在哪里?__->C(数据段)-`localVar`在哪里?__->A(栈)-`num1`在哪里?__->A(栈)-`char2`在哪里?__->A(栈)-`*char2`在哪里?__->A(栈)// 注意:char2是一个数组,数组在栈上,所以数组元素也在栈上-`pChar3`在哪里?__->A(栈)-`*pChar3`在哪里?__->D(代码段/常量区)// pChar3指向一个字符串常量,字符串常量在代码段/常量区-`ptr1`在哪里?__->A(栈)-`*ptr1`在哪里?__->B(堆)

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

voidTest(){int*p1=(int*)malloc(sizeof(int)*4);// 分配未初始化的内存int*p2=(int*)calloc(4,sizeof(int));// 分配并初始化为0int*p3=(int*)realloc(p2,sizeof(int)*10);// 调整内存大小// 不需要free(p2),因为realloc已经处理free(p1);free(p3);}

malloc/calloc/realloc的区别?

- malloc:申请指定字节数的内存,不初始化。 - calloc:为指定数量的元素分配内存,每个元素的大小为指定字节数,并将内存初始化为0。 - realloc:调整已分配内存块的大小,可以扩大或缩小。扩大时,原内容保留,新增部分不初始化;缩小时,截断部分内容。可能移动内存块到新的位置
函数初始化参数功能
malloc不初始化size分配指定字节数的内存
calloc初始化为0num, size分配num个size字节的元素
realloc保持原内容ptr, new_size调整已分配内存的大小

malloc的实现原理?glibc中malloc实现原理

- malloc的实现原理通常涉及内存池管理,使用空闲链表(free list)来管理已释放的内存块,并通过brk或mmap系统调用向操作系统申请内存。glibc的malloc使用ptmalloc2实现,它通过维护多个内存块(chunk)和多个链表来管理内存,包括未分配的内存和已分配的内存,并尝试减少内存碎片。

c++内存管理方式 new和delete

voidTest(){// 动态申请一个int类型的空间int*ptr4=newint;// 动态申请一个int类型的空间并初始化为10int*ptr5=newint(10);// 动态申请10个int类型的空间int*ptr6=newint[3];deleteptr4;deleteptr5;delete[]ptr6;}注意:申请和释放单个元素的空间,使用newdelete操作符,申请和释放连续的空间,使用new[]delete[],注意匹配起来使用。

new和delete操作自定义类型

classA{public:A(inta=0):_a(a){cout<<"A():"<<this<<endl;}~A(){cout<<"~A():"<<this<<endl;}private:int_a;};intmain(){// new/delete和malloc/free最大区别是new/delete对于【自定义类型】除了开空间还会调用构造函数和析构函数A*p1=(A*)malloc(sizeof(A));A*p2=newA(1);free(p1);deletep2;// 内置类型是几乎是一样的int*p3=(int*)malloc(sizeof(int));// Cint*p4=newint;free(p3);deletep4;A*p5=(A*)malloc(sizeof(A)*10);A*p6=newA[10];free(p5);delete[]p6;return0;}在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与free不会。

operator new与operator delete函数

/* operator new:该函数实际通过malloc来申请空间,当malloc申请空间成功时直接返回;申请空间失败,尝试执行空间不足应对措施,如果改应对措施用户设置了,则继续申请,否则抛异常。 */void*__CRTDECLoperatornew(size_t size)_THROW1(_STD bad_alloc){// try to allocate size bytesvoid*p;while((p=malloc(size))==0)if(_callnewh(size)==0){// report no memory// 如果申请内存失败了,这里会抛出bad_alloc类型异常staticconststd::bad_alloc nomem;_RAISE(nomem);}return(p);}/* operator delete: 该函数最终是通过free来释放空间的 */voidoperatordelete(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的实现**加粗样式**#definefree(p)_free_dbg(p,_NORMAL_BLOCK)// operator new 的简化实现void*operatornew(size_t size){void*p;while((p=malloc(size))==0){// 尝试处理内存不足的情况if(处理函数==0){// 抛出bad_alloc异常throwstd::bad_alloc();}}returnp;}// operator delete 的简化实现voidoperatordelete(void*p){free(p);}

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

new和delete的实现原理

如果申请的是内置类型的空间,new和malloc,delete和free基本类似,不同的地方是:new/delete申请和释放的是单个元素的空间,new[]和delete[]申请的是连续空间,而且new在申请空间失败时会抛异常,malloc会返回NULL。

自定义类型

  • new的原理
    1. 调用operator new函数申请空间
    2. 在申请的空间上执行构造函数,完成对象的构造
  • delete的原理
    1. 在空间上执行析构函数,完成对象中资源的清理工作
    2. 调用operator delete函数释放对象的空间
  • new T[N]的原理
    1. 调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对象空间的申请
    2. 在申请的空间上执行N次构造函数
  • delete[]的原理
    1. 在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理
    2. 调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释放空间

定位new表达式(placement-new)

new(place_address)type;new(place_address)type(initializer-list);

其中,place_address必须是一个指针,initializer-list是类型的初始化列表。

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

classA{public:A(inta=0):_a(a){cout<<"A():"<<this<<endl;}~A(){cout<<"~A():"<<this<<endl;}private:int_a;};// 定位new/replacement newintmain(){// p1现在指向的只不过是与A对象相同大小的一段空间,还不能算是一个对象,因为构造函数没有执行A*p1=(A*)malloc(sizeof(A));new(p1)A;// 注意:如果A类的构造函数有参数时,此处需要传参p1->~A();free(p1);A*p2=(A*)operatornew(sizeof(A));new(p2)A(10);p2->~A();operatordelete(p2);return0;}

malloc/free 和 new/delete 的区别

特性malloc/freenew/delete
性质函数操作符
初始化不初始化可以初始化
空间计算手动计算字节数自动计算类型大小
返回值void* 需要强转返回具体类型指针
失败处理返回NULL抛出异常
自定义类型不调用构造/析构调用构造/析构
重载不可重载可重载operator new/delete
内存来源可自定义(placement-new

malloc/free和new/delete的共同点是:都是从堆上申请空间,并且需要用户手动释放。不同的地方是:

  1. malloc和free是函数,new和delete是操作符
  2. malloc申请的空间不会初始化,new可以初始化
  3. malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可,如果是多个对象,[]中指定对象个数即可
  4. malloc的返回值为void*,在使用时必须强转,new不需要,因为new后跟的是空间的类型
  5. malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需要捕获异常
  6. 申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理

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

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

相关文章

Java毕设项目推荐-基于SpringBoot的水族馆线下门店与线上销售的一体化管理系统基于SpringBoot的水族馆商品销售与经营管理系统【附源码+文档,调试定制服务】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

C语言内存函数:介绍使用及其模拟实现

memcpy - 内存拷贝 void *memcpy(void *destination, const void *source, size_t num);从source位置开始向后复制num个字节到destination指向的内存位置不会在遇到’\0’时停下来如果source和destination有重叠&#xff0c;复制结果是未定义的适用于非重叠内存区域的拷贝 使用…

初识Jmeter

1、Jmeter体系结构元件&#xff1a;代表Jmeter工具菜单中的一个子菜单&#xff08;功能&#xff09;&#xff0c;比如HTTP请求、事务控制器、响应断言等&#xff0c;就是一个元件。多个类似功能组件的容器&#xff08;类似于类&#xff09;常见的元件类型有&#xff1a; 1. 取样…

技术资产管理:智能复用评估

技术资产管理:智能复用评估 关键词:技术资产管理、智能复用评估、技术复用、资产价值评估、技术资源优化 摘要:本文聚焦于技术资产管理中的智能复用评估这一关键议题。首先阐述了技术资产管理及智能复用评估的背景,明确目的、范围、预期读者等内容。接着详细介绍核心概念与…

【计算机毕业设计案例】基于SpringBoot的大学生综合素质测评系统设计与实现基于SpringBoot的学生身体素质测评管理系统(程序+文档+讲解+定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

【计算机毕业设计案例】基于SpringBoot的水族馆鱼类商品销售与经营管理系统基于SpringBoot的水族馆商品销售与经营管理系统(程序+文档+讲解+定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

无线网络仿真:6G网络仿真_(19).6G网络仿真未来趋势

6G网络仿真未来趋势 1. 6G网络仿真概述 6G网络仿真是在6G网络研究和开发中不可或缺的一部分。通过仿真&#xff0c;研究人员可以验证理论模型、评估网络性能、测试新算法和技术&#xff0c;以及预测未来网络的行为。6G网络仿真不仅涵盖了传统的无线通信仿真技术&#xff0c;还引…

无线网络仿真:6G网络仿真_(20).6G网络仿真实践项目

6G网络仿真实践项目 项目背景 随着5G技术的普及和6G技术的研究不断深入&#xff0c;无线网络仿真成为研究和开发6G网络的关键工具之一。6G网络仿真不仅能够帮助研究人员验证新的通信协议和算法&#xff0c;还能为网络规划和优化提供有价值的参考。本节将详细介绍一个具体的6G网…

无线网络仿真:Wi-Fi网络仿真_(3).仿真软件介绍与使用

仿真软件介绍与使用 在进行无线网络仿真时&#xff0c;选择合适的仿真软件至关重要。本节将详细介绍几种常用的Wi-Fi网络仿真软件&#xff0c;包括NS-3、OMNeT和MATLAB&#xff0c;并提供具体的使用方法和示例代码。 NS-3 仿真软件 NS-3&#xff08;Network Simulator 3&#x…

无线网络仿真:6G网络仿真_(15).6G网络仿真参数设置

6G网络仿真参数设置 在进行6G网络仿真时&#xff0c;参数设置是至关重要的一步。合理的参数设置不仅能够确保仿真的准确性&#xff0c;还能有效提升仿真的效率。本节将详细讨论6G网络仿真的参数设置&#xff0c;包括物理层参数、链路层参数、网络层参数和应用层参数。我们将结合…

智能编程平台:低代码开发实践

智能编程平台&#xff1a;低代码开发实践关键词&#xff1a;智能编程平台、低代码开发、开发实践、可视化编程、自动化代码生成摘要&#xff1a;本文围绕智能编程平台的低代码开发实践展开。首先介绍了低代码开发的背景和相关概念&#xff0c;包括目的、预期读者、文档结构等。…

大数据浪潮下,ClickHouse的破局之道

大数据浪潮下,ClickHouse的破局之道:从原理到实践的实时分析加速指南 引言:当大数据分析遇到“慢”的瓶颈 深夜11点,电商数据分析师小周盯着电脑屏幕皱起眉头——他要统计“双11”当天10亿条用户行为数据中的Top10热门商品,用Hive跑查询已经等了40分钟,结果还没出来。而…

大数据建模中的向量化处理:SIMD指令优化计算

大数据建模中的向量化处理&#xff1a;SIMD指令优化计算——从"单柜台结账"到"流水线工厂"的效率革命 关键词 SIMD指令集、向量化处理、数据并行、指令级并行、缓存友好、大数据建模、CPU优化 摘要 在大数据建模场景中&#xff0c;计算效率是制约模型训练速…

别再重复造轮子!AI应用架构师:企业AI中台可复用组件库建设,附开发规范

别再重复造轮子&#xff01;AI应用架构师&#xff1a;企业AI中台可复用组件库建设&#xff0c;附开发规范 关键词&#xff1a;AI中台、可复用组件库、开发规范、企业AI应用、架构设计、AI技术整合、组件化开发 摘要&#xff1a;本文深入探讨企业AI中台可复用组件库的建设。从…

这3个内幕曝光,了解洁净室专用电话机的技术内核!

“看似简单的【洁净室专用电话机】,选错细节可能导致交叉污染风险、通讯中断、降级失败。” 作为制药厂、实验室洁净室工程的常用通讯设备,一部功能可靠的洁净室专用电话机至关重要。它不仅关乎信息传递的效率,更直接关系到洁净环境的维持与合规性。然而,许多用户甚至采购商…

计算机毕设 java 基于协同过滤算法的就业推荐系统的设计与实现 基于协同过滤算法的智能就业推荐平台 求职与企业招聘匹配系统

计算机毕设 java 基于协同过滤算法的就业推荐系统的设计与实现&#xff08;配套有源码、程序、MySQL 数据库、论文&#xff09;&#xff0c;本套源码可先查看功能演示视频&#xff0c;文末有联xi 可分享c系统核心功能涵盖注册登录、个人中心、多角色管理&#xff08;管理员、用…

【毕业设计】基于Java的学生身体素质测评管理系统基于SpringBoot的学生身体素质测评管理系统(源码+文档+远程调试,全bao定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

计算机毕设 java 基于智能机器人的智能答疑系统的设计与实现 基于智能机器人的交互式答疑平台 师生问答与知识交流系统

计算机毕设 java 基于智能机器人的智能答疑系统的设计与实现&#xff08;配套有源码、程序、MySQL 数据库、论文&#xff09;&#xff0c;本套源码可先查看功能演示视频&#xff0c;文末有联xi 可分享传统答疑模式存在响应不及时、交流效率低、资源共享不足等问题&#xff0c;影…

【信号处理】通过 “最近邻匹配” 和 “球面线性插值(SLERP)” 两种方式将 GNSS 位姿(位置 + 四元数)插值到激光雷达时间戳附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f447; 关注我领取海量matlab电子书和数学建模资料 &#x1f34…

【单相STATCOM】单相STATCOM在单相系统中补偿无功功率,并减轻谐波附Simulink仿真

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f34a;个人信条&#xff1a;格物致知,完整Matlab代码及仿真咨询…