新闻详情

新闻详情

首页 / 资讯中心 / 详情

C\C++ 内存管理

发布时间:2026/9/11 11:27:21来源:尧图网络
C\C++ 内存管理
本篇文章主要介绍在C语言的内存管理的基础上C的内存管理方式1.C\C 内存分布C和C内存分布主要是 栈堆静态区数据段常量区代码段还有一块内存映射段。各个区别如下栈Stack由操作系统自动管理自动分配、自动释放不需要手动申请释放。存放函数局部变量、函数形参、函数返回地址、临时变量。栈空间很小一般几 MB生长方向向下向低地址增长。函数调用结束栈帧直接销毁局部变量立刻失效。栈内存不会产生内存泄漏但容易栈溢出比如递归过深、定义超大局部数组。堆Heap由程序员手动管理C 用malloc/freeC 用new/delete。需要手动申请内存使用完必须手动释放否则发生内存泄漏。堆空间很大远大于栈生长方向向上向高地址增长。用于存放程序运行时才确定大小的数据动态开辟的对象、数组都放在堆上。堆内存释放后要避免野指针问题。静态区数据段分为初始化数据段、未初始化数据段 (BSS 段)。存放全局变量、static 静态变量。程序启动时分配程序结束才释放生命周期是整个程序运行周期。 初始化数据段存放已经初始化的全局变量、static 静态变量 BSS 段存放未初始化的全局变量、静态变量程序加载时系统自动置 0。常量区 / 代码段Text 段代码段存放程序编译后的机器指令二进制代码常量区一般附属在代码段存放字符串字面量、const修饰的全局常量。该区域内存只读不允许修改尝试写操作会触发程序崩溃。生命周期贯穿整个程序程序退出由系统回收。注意局部 const 变量不在常量区在栈上。内存映射段mmap 映射区位于堆和栈之间。用来做文件映射、动态链接库.so 加载、匿名内存映射。操作系统把磁盘文件直接映射到虚拟内存程序可以直接像访问内存一样读写文件不需要频繁 read/write 系统调用。也用于大内存分配当 malloc 申请超大块内存时系统不走堆直接使用 mmap 开辟。这部分内存由操作系统管理。下面我们结合代码和图片来理解一下2.C语言中动态内存管理方式malloc/calloc/realloc/freemalloc申请 size 字节堆内存内存不初始化。void* malloc(size_t size);calloc申请 num 个、每个 size 字节的堆内存分配后自动置 0。void* calloc(size_t num, size_t size);realloc重新修改已有堆内存的大小可以扩容也可以缩容不一定在原地址操作。void* realloc(void* ptr, size_t new_size);free:就是把开辟的空间归还给操作系统。3.C内存管理方式C语言内存管理方式在C中可以继续使用但有些地方就无能为力而且使用起来比较麻烦因此C又提出了自己的内存管理方式通过new和delete操作符进行动态内存管理。3.1new/delete操作内置类型void Test() { // 动态申请一个int类型的空间 int* ptr4 new int; // 动态申请一个int类型的空间并初始化为10 int* ptr5 new int(10); // 动态申请10个int类型的空间 int* ptr6 new int[3]; delete ptr4; delete ptr5; delete[] ptr6; }注意申请和释放单个元素的空间使用new和delete操作符申请和释放连续的空间使用new[]和delete[]注意匹配起来使用。3.2new和delete操作自定义类型使用new 为自定义类型开辟空间的方法和内置类型一样delete 释放空间的使用方法也是一样的但是和内置类型的区别是new为自定义类型开辟空间后会调用构造函数delete在释放空间前会调用析构函数。class A { public: A(int a 0) : _a(a) { cout A(): this endl; } ~A() { cout ~A(): this endl; } private: int _a; }; int main() { // new/delete 和 malloc/free最大区别是 new/delete对于【自定义类型】除了开空间 //还会调用构造函数和析构函数 A* p1 (A*)malloc(sizeof(A)); A* p2 new A(1); free(p1); delete p2; // 内置类型是几乎是一样的 int* p3 (int*)malloc(sizeof(int)); int* p4 new int; free(p3); delete p4; A* p5 (A*)malloc(sizeof(A) * 10); A* p6 new A[10]; free(p5); delete[] p6; return 0; }4.operator new与operator delete函数new和delete是用户进行动态内存申请和释放的操作符operator new和operator delete是系统提供的全局函数new在底层调用operator new全局函数来申请空间delete在底层通过operator delete全局函数来释放空间。其次就是operator new实际也是通过malloc来申请空间如果 malloc申请空间成功就直接返回否则执行用户提供的空间不足应对措施如果用户提供该措施 就继续申请否则就抛异常。operator delete最终是通过free来释放空间的。这里主要是说明new在开辟空间后不需要像malloc那样检查是否为空只要捕获异常即可。5.new和delete的实现原理5.1内置类型如果申请的是内置类型的空间new和mallocdelete和free基本类似不同的地方是new/delete申请和释放的是单个元素的空间new[]和delete[]申请的是连续空间而且new在申请空间失败时会抛异常malloc会返回NULL。5.2自定义类型new原理1.调用operator new函数申请空间2.在申请的空间上执行构造函数完成对象的构造delete原理1.在空间上执行析构函数完成对象中资源的清理工作2.调用operator delete函数释放对象的空间new[ N ]原理1.调用operatornew[]函数在operatornew[]中实际调用operatornew函数完成N个对象空间的申请2.在申请的空间上执行N次构造函数delete[ N ] 原理1.在释放的对象空间上执行N次析构函数完成N个对象中资源的清理2.调用operator delete[]释放空间实际在operator delete[]中调用operator delete来释放空间6.定位new表达式定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象。使用格式new (place_address) type或者new (place_address) type(initializer-list)place_address必须是一个指针initializer-list是类型的初始化列表比如下面的程序class A { public: A(int a 0) : _a(a) { cout A(): this endl; } ~A() { cout ~A(): this endl; } private: int _a; }; // 定位new/replacement new int main() { // p1现在指向的只不过是与A对象相同大小的一段空间还不能算是一个对象因为构造函数没有执行 A* p1 (A*)malloc(sizeof(A)); new(p1)A; //注意如果A类的构造函数有参数时此处需要传参 p1-~A(); free(p1); A* p2 (A*)operator new(sizeof(A)); new(p2)A(10); p2-~A(); operator delete(p2); return 0; }定位new表达式使用较多的场景是配合内存池使用因为内存池分配出的内存没有初始化所以如果是自定义类型的对象需要使用new的定义表达式进行显示调构造函数进行初始化。7.malloc/free和new/delete的区别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在释放空间前会调用析构函数完成空间中资源的清理释放
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Workflow与ReAct架构抉择:控制权分配的工程实践指南 2026/9/11 11:26:07

Workflow与ReAct架构抉择:控制权分配的工程实践指南

1. 这不是“选哪个更好”,而是“在什么现场,用什么扳手”“给 LLM 多大的自由空间”——这句话听起来像哲学思辨,但在我过去三年带团队落地 17 个生产级 AI 应用的过程中,它每天都在真实发生:客服工单自动归因系统上线…

阅读更多 →
MATLAB在遥感时序数据处理与植被分析中的应用 2026/9/11 11:26:07

MATLAB在遥感时序数据处理与植被分析中的应用

1. MATLAB在长时间序列遥感数据处理中的应用全景遥感数据时间序列分析是理解地球系统动态变化的核心手段。作为工程计算领域的标杆工具,MATLAB凭借其强大的矩阵运算能力和丰富的工具箱,在遥感数据处理链条中展现出独特优势。我处理过从Landsat到MODIS的各…

阅读更多 →
电力系统双侧电源方向性电流保护原理与Simulink建模 2026/9/11 11:26:07

电力系统双侧电源方向性电流保护原理与Simulink建模

1. 项目背景与核心价值双侧电源相间短路方向性电流保护是电力系统继电保护领域的关键技术。在复杂电网结构中,当线路两侧都有电源接入时,传统的过电流保护无法准确判断故障方向,可能导致保护误动或拒动。这个问题在分布式电源大量接入的现代电…

阅读更多 →
软件工程核心原则与开发实践指南 2026/9/11 11:26:07

软件工程核心原则与开发实践指南

1. 软件工程基础概念与核心原则 软件工程作为一门系统化的学科,其基础概念构成了整个知识体系的根基。在近十年的项目实践中,我发现很多开发者在面对复杂系统时,往往因为基础概念模糊而导致架构设计出现根本性偏差。 软件工程最核心的定义是…

阅读更多 →
Dolphin 安装上手教程:5 分钟从源码跑通 GameCube 与 Wii 模拟器 2026/9/11 11:26:07

Dolphin 安装上手教程:5 分钟从源码跑通 GameCube 与 Wii 模拟器

Dolphin 安装上手教程:5 分钟从源码跑通 GameCube 与 Wii 模拟器 【免费下载链接】dolphin Dolphin is a GameCube / Wii emulator, allowing you to play games for these two platforms on PC with improvements. 项目地址: https://gitcode.com/GitHub_Trendin…

阅读更多 →
Web技术演进与工程实践:从静态页面到AI驱动的智能化应用 2026/9/11 11:23:05

Web技术演进与工程实践:从静态页面到AI驱动的智能化应用

从1991年第一个网页诞生到今天,Web已经走过了三十多年。我入行时还在用table布局切图,现在已经带着团队做AI驱动的Web应用,回头看这条演进路线,其实有一条非常清晰的主线: 每一次Web技术的跃迁,本质上都是…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞