C++内存管理:从内存分布到new/delete底层原理
一、C/C内存分布在开始讨论动态内存管理之前我们先来搞清楚一个问题程序中的各种变量分别存储在内存的哪个区域先看下面这段代码int globalvar 1; static int staticGlobalvar 1; void Test() { static int staticvar 1; int localvar 1; int num1[10] {1,2,3,4}; char char2[] abcd; const char* 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); }你能准确说出每个变量存储在哪个区域吗globalvar→ 数据段静态区staticGlobalvar→ 数据段静态区staticvar→ 数据段静态区localvar→ 栈num1→ 栈char2→ 栈*char2→ 栈因为char2是数组内容在栈上pChar3→ 栈*pChar3→ 代码段常量区因为指向的是字符串常量ptr1→ 栈*ptr1→ 堆内存区域划分区域存储内容特点栈非静态局部变量、函数参数、返回值等向下增长自动管理堆动态分配的内存向上增长需手动管理数据段静态区全局变量、静态变量程序运行时分配结束时释放代码段常量区可执行代码、只读常量只读不可修改二、C语言的动态内存管理在C语言中我们使用malloc、calloc、realloc和free来管理动态内存。malloc/calloc/realloc 的区别函数参数初始化返回值malloc字节数不初始化void*calloc个数每个大小初始化为0void*realloc原指针新大小不初始化void*// 使用示例 int* p2 (int*)malloc(4 * sizeof(int)); // 申请4个int int* p3 (int*)calloc(4, sizeof(int)); // 申请4个int并初始化为0 int* p4 (int*)realloc(p2, sizeof(int)*10); // 扩容到10个int // 注意如果realloc扩容成功p2会被自动释放不需要再free(p2) free(p3); free(p4);三、C的内存管理方式C除了兼容C的内存管理方式外还引入了new和delete操作符。3.1 内置类型的使用// 申请和释放单个对象 int* ptr1 new int; // 申请一个int int* ptr2 new int(10); // 申请一个int并初始化为10 delete ptr1; delete ptr2; // 申请和释放数组 int* ptr3 new int[10]; // 申请10个int delete[] ptr3; // 注意必须使用delete[]3.2 自定义类型的使用new和delete与malloc和free最大的区别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() { // malloc只会开辟空间不会调用构造函数 A* p1 (A*)malloc(sizeof(A)); // new会开辟空间 调用构造函数 A* p2 new A(10); // free只会释放空间不会调用析构函数 free(p1); // delete会调用析构函数 释放空间 delete p2; return 0; }四、operator new 与 operator delete很多人不知道的是new和delete实际上是操作符而operator new和operator delete是全局函数。底层实现原理// operator new 的简化实现 void* __CRTDECL operator new(size_t size) { void* p; while ((p malloc(size)) 0) { if (_callnewh(size) 0) { // 申请失败抛出 bad_alloc 异常 throw std::bad_alloc(); } } return p; } // operator delete 的简化实现 void operator delete(void* pUserData) { if (pUserData NULL) return; free(pUserData); }关键点operator new底层调用malloc申请失败时抛异常而不是返回NULLoperator delete底层调用free五、new 和 delete 的实现原理5.1 内置类型对于内置类型new和malloc、delete和free基本类似区别在于new失败时抛异常malloc失败返回NULLnew[]/delete[]用于连续空间5.2 自定义类型new的原理调用operator new申请空间在申请的空间上执行构造函数delete的原理在空间上执行析构函数调用operator delete释放空间new T[N]的原理调用operator new[]实际调用operator new申请N个对象空间执行N次构造函数delete[]的原理执行N次析构函数调用operator delete[]实际调用operator delete释放空间六、定位new表达式placement new定位new允许在已分配的内存上调用构造函数初始化对象。// 使用场景内存池分配的内存需要初始化 A* p1 (A*)malloc(sizeof(A)); // 只分配内存未构造对象 new(p1) A(10); // 在p1指向的内存上构造对象 p1-~A(); // 显式调用析构函数 free(p1);适用场景配合内存池使用在已分配的内存上创建对象。七、malloc/free 与 new/delete 的区别对比项malloc/freenew/delete本质函数操作符初始化不会初始化可以初始化大小计算需手动计算编译器自动计算返回值void*需强转类型安全无需强转失败处理返回NULL需判空抛异常需捕获自定义类型不调用构造/析构调用构造/析构八、常见问题与最佳实践8.1 内存泄漏内存泄漏是指动态分配的内存没有被正确释放导致内存浪费。常见场景忘记delete/free异常导致delete未执行使用new[]却用delete释放8.2 最佳实践匹配使用new配deletenew[]配delete[]RAII原则使用智能指针unique_ptr、shared_ptr管理资源避免裸指针尽可能使用智能指针定期检查使用内存检测工具定期检查内存泄漏总结C的内存管理非常灵活但也很容易出错。记住以下几点理解内存分布栈、堆、数据段、代码段掌握new/delete与malloc/free的区别理解operator new/operator delete的底层原理遵循最佳实践使用智能指针管理内存

相关新闻

免费分屏神器:Nucleus Co-Op 开启多人同屏游戏新时代

免费分屏神器:Nucleus Co-Op 开启多人同屏游戏新时代

免费分屏神器:Nucleus Co-Op 开启多人同屏游戏新时代 【免费下载链接】nucleuscoop Starts multiple instances of a game for split-screen multiplayer gaming! 项目地址: https://gitcode.com/gh_mirrors/nu/nucleuscoop 还在为无法与朋友共享同一台电脑畅…

2026/10/25 19:50:23 阅读更多 →
Godot集成WebAssembly实战:用Rust提升游戏性能与跨语言开发

Godot集成WebAssembly实战:用Rust提升游戏性能与跨语言开发

1. 项目概述:为什么要在Godot里集成WebAssembly?如果你是一个Godot开发者,最近可能听到过“WebAssembly”或者“Wasm”这个词。它不再是浏览器里的一个遥远概念,而是正在成为高性能、跨语言游戏逻辑扩展的一个现实选择。简单来说&…

2026/10/23 21:20:25 阅读更多 →
OpenClaw:云服务器AI管理工具一键配置与安全实践

OpenClaw:云服务器AI管理工具一键配置与安全实践

1. OpenClaw项目概述 OpenClaw是一款面向云服务器环境设计的AI辅助工具,主打"云上养虾"场景的智能化管理。这个开源项目最近在开发者社区热度攀升,主要得益于其宣称的三大特性:一键配置的简易性、云环境适配的安全性,以…

2026/10/25 12:15:26 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/28 23:48:14 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/29 8:45:01 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/29 9:52:56 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/28 22:10:30 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/29 9:51:34 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/29 8:44:28 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/28 16:58:40 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/29 9:42:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/28 19:25:09 阅读更多 →