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/9/29 23:27:27 阅读更多 →
Godot集成WebAssembly实战:用Rust提升游戏性能与跨语言开发

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

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

2026/9/28 20:44:03 阅读更多 →
OpenClaw:云服务器AI管理工具一键配置与安全实践

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

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

2026/9/27 12:21:27 阅读更多 →

最新新闻

CentOS 8 安装图解:从镜像校验到首次登录的完整指南

CentOS 8 安装图解:从镜像校验到首次登录的完整指南

简介:这份资源是一份面向Linux初学者与运维入门者的CentOS 8安装图解教程,以PDF形式呈现,重点解决新手在虚拟机环境中安装CentOS 8时步骤不清、配置易错的问题。压缩包内共1个PDF文件,大小约1.29MB,内容以图文结合方式…

2026/9/30 15:36:16 阅读更多 →
Java异常处理实战:高频错误排查、性能优化与面试指南

Java异常处理实战:高频错误排查、性能优化与面试指南

做Java开发这些年,天天跟异常打交道。NullPointerException、ConcurrentModificationException、ClassCastException……光是这几个高频错误就已经劝退了不少刚入行的朋友。异常处理这件事,看起来只是try-catch-finally几个关键字,但真正到了…

2026/9/30 15:36:16 阅读更多 →
基于NSGA-III的梯级水电与火电联合调度优化及MATLAB实现

基于NSGA-III的梯级水电与火电联合调度优化及MATLAB实现

做电力调度优化的同行,多少都遇过这种场景:系统里既有火电也有梯级水电,火电煤耗曲线是非线性的,水电又受来水、库容和上下游关系的多重限制,两边纠缠在一起,靠人工或者单目标优化很难给出让人满意的方案。…

2026/9/30 15:36:16 阅读更多 →
从参数破解到官方API:用PyQt5搭建数据可视化小工具

从参数破解到官方API:用PyQt5搭建数据可视化小工具

今年五一没有出门凑热闹,宅在家里把一个想了很久的项目落地了:做一个小工具,把头条系账号的内容数据集中到一个可视化的界面里,方便每天查看。在动手之前圈子里不少人提过“某头条参数破解”这个方向,我一开始也确实往…

2026/9/30 15:36:16 阅读更多 →
U-Boot设备模型解析:board_init_r中的dm骨架搭建与probe机制

U-Boot设备模型解析:board_init_r中的dm骨架搭建与probe机制

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

2026/9/30 15:36:16 阅读更多 →
软件测试面试高频题解析:从理论到项目实战

软件测试面试高频题解析:从理论到项目实战

面试这件事,我见过太多人把精力花错了地方。背了一堆八股文,结果面试官一句“说说你印象最深的一个Bug”就卡壳了。也有不少人简历写得花团锦簇,一到项目追问环节就露馅。做软件测试这些年,我面试过别人,也被别人面试过…

2026/9/30 15:35:15 阅读更多 →

日新闻

Base64 图片头部特征识别:从文件头到格式判断的完整指南

Base64 图片头部特征识别:从文件头到格式判断的完整指南

1. 项目概述:为什么说看懂 base64 图片头部是基本功这几年跟 base64 打交道的机会越来越多,后端接口返回图片、前端渲染验证码、小程序里存小图、还有一些老系统导出报表,动不动就给你一段长到怀疑人生的 base64 字符串。很多人拿到字符串就直…

2026/9/30 0:00:35 阅读更多 →
Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

简介:本资源是一份面向Java初学者与课程设计学生的公交站牌广告灯箱管理系统毕业设计文档,聚焦城市公共广告资源信息化管理痛点,提供从需求分析到技术实现的完整方案。文档采用标准学术论文结构,含摘要、英文摘要、目录及五章正文…

2026/9/30 0:00:35 阅读更多 →
用 Redis Lua 构建大模型 API 多租户原子配额治理体系

用 Redis Lua 构建大模型 API 多租户原子配额治理体系

我去年年底接了一个内部 AI 平台的治理需求,背景很直接:公司把 DeepSeek、MiniMax 这类大模型 API 统一封装成内部网关,开放给几个业务团队用。结果第一个月账单出来,额度直接超了 4 倍。仔细查日志,发现原因并不复杂—…

2026/9/30 0:00:35 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/30 13:14:22 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/29 16:41:41 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/9/30 13:14:49 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/29 19:29:29 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/29 5:58:00 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/30 15:27:04 阅读更多 →